依赖注入
# 依赖注入
# servlet生命周期
初始化方法init(),一个带参数void init(ServletConfig config),另一个无参void init()。可以重写init()进行准备工作,还可以初始化设置参数。
web.xml配置初始化变量,通过键值对的方式,要在servlet这一级下进行配置。
<servlet> <init-param> <param-name>name</param-name> <param-value>cungu</param-value> </init-param> </servlet>1
2
3
4
5
6在init()中通过getServletConfig()拿到配置,然后getInitParameter(key)取拿到值
public void init() throws ServletException { ServletConfig config= getServletConfig(); String value = config.getInitParameter("name");}1
2
3web.xml配置上下文变量,注意要在servlet外面一级
<context-param> <param-name>contextkey</param-name> <param-value>contextvalue</param-value> </context-param>1
2
3
4通过ServletContext拿到初始化值
ServletContext servletContext = getServletContext(); String contextValue =servletContext.getInitParameter("contextkey");1
2
# MVC业务层BO和DAO层
业务层属于粗粒度方法,DAO属于细粒度方法。
在DAO层的外层再创建一层业务层(接口+impl),当遇到复杂的业务时需要同时使用DAO层的多条sql语句。其中fruitServiceImpl里sql语句通过fruitDaoImpl调用实现。
# IOC实现
代码层与层之间关系要尽量保证低耦合,核心思想依赖注入。
首先把每个类里面用到的其它类实例变量都赋值为null,进行解耦。
每个类和该类调用其它类实例依赖信息都注册到依赖文件中。
<bean id="fruitdao" class="dao.impl.FruitDAOImpl"></bean> <bean id="fruit" class="controller.FruitController"> <!-- ref对应上面的bean id,表示引用,而name表示属性名--> <property name="fruitdao" ref="fruitdao"></property> </bean>1
2
3
4
5解析xml文件,通过输入流创建文件工厂,然后拿到依赖文件所有bean节点
把每个节点从Node类型转换成Element类型,通过getAttribute方法来获取每个bean标签中的id名称和class名称,再利用类名反射创建实例对象,然后丢到beanMap中
然后进行依赖注入,被调用类实例注入到调用类的property属性中
- 重新遍历所有bean节点,通过getChildNode()获取子节点列表,查看是否有子元素节点,若有元素节点表明存在依赖关系
- 通过getAttribute拿到name和ref值,name表示当前bean节点调用其它类实例的变量名。从beanMap中可以拿到当前bean和ref的实例对象
- 然后用当前bean的名字/类实例通过反射获取到name的Field,然后通过set方法进行注入这两个实例。
for (int j = 0; j < beanChildNodeList.getLength(); j++) {
Node beanChildNode = beanChildNodeList.item(j);
if (beanChildNode.getNodeType() == Node.ELEMENT_NODE && beanChildNode.getNodeName().equals("property")) {
Element propertyNode = (Element) beanChildNode;
String propertyName = propertyNode.getAttribute("name");
String propertyRef = propertyNode.getAttribute("ref");
//拿到引用对象的实例
Object refObj = beanMap.get(propertyRef);
//拿到当前bean节点的实例
Object beanObj = beanMap.get(beanId);
//把refobj设置到当前bean实例的property属性上
Class beanClass=beanObj.getClass();
Field propertyField = beanClass.getDeclaredField(propertyName);
propertyField.setAccessible(true);
propertyField.set(beanObj,refObj);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
编辑 (opens new window)
上次更新: 2023/12/15, 15:49:57