依赖注入(DI)背后的基本原理是对象之间的依赖关系(即一起工作的其它对象)。因此,容器的工作就是创建bean时注入那些依赖关系。相对于由bean自己来控制其实例化、直接在构造器中指定依赖关系或者类似服务定位器(Service Locator)模式这3种自主控制依赖关系注入的方法来说,控制从根本上发生了倒转,这也正是控制反转(Inversion of Control, IoC) 名字的由来。
setter注入是spring根据配置文件自动完成的,你不需要在程序中显示的调用,因此代码没有与spring框架直接耦合。
而通过getBean方法则首先意味着你必须获取到BeanFactory或ApplicationContext,这种方式叫依赖查找,代码了解框架的存在,耦合度较高。
应用DI原则后,代码将更加清晰。而且当bean自己不再担心对象之间的依赖关系(甚至不知道依赖在哪里定义和依赖的实际类)之后,实现更高层次的松耦合将易如反掌。DI有三种注入方式,即Setter注入(*.这个是最重要和最主要的,企业用的最多且最灵活的)、构造器注入和接口注入。
项目源码是接http://moshowgame.iteye.com/admin/blogs/1605087的。但是只有一个地方改了(就是UserService里面加了个默认构造函数),但是总体结构没变。这里只讲解XML,前面的model、DAO、DAO.impl和service就不再重复说了。
*。在bean.xml配置setter注入和constructor注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="userDAOImpl" class="com.bjsxt.dao.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.bjsxt.service.UserService">
<!-- setter设置注入就是调用setXXX方法,但是需要保留默认构造方法-->
<!--
<property name="userDAO" ref="userDAOImpl" />
-->
<!-- constructor构造注入调用的是构造方法-->
<!--
<constructor-arg index="0">
<ref bean="userDAOImpl"/>
</constructor-arg>
-->
</bean>
</beans>
*。上面两种方法写在一起了,要用的方法请取消掉<!-- -->的注释,然后将另外的方法用<!-- -->注释掉。
*。注入的思路。等于就是说从UserDAOImpl中new一个UserDAO的实例userDAO,然后注入到UserService里面的setter或constructor里面。用spring的方式讲就是参考bean获得实例然后注入到目标bean里面去,即是要用到两个bean。
*。常见错误1。用setter设置注入需要保留默认构造方法,不然会报错,我就是这样错了一个下午,问大神才知道的。
public UserService() {}
用constructor构造注入需要重写构造方法并且带参数 public UserService(UserDAO userDAO) {
super();
this.userDAO = userDAO;
}
*。常见错误2。<property name="userDAO"..这里的userDAO名字要和public UserService(UserDAO userDAO)的userDAO一致,才能确认不会注入错,下午也因为这个错了。
*。很多东西刚开始觉得很难,学过了之后、练过了之后、错过了之后才明白,其实很简单。
⊙_⊙最后,按照我的惯例,附上本次的项目源码,类库用到三个(spring.jar junit.jar(eclipse自带) commons-logging.jar)。
^_^还有什么好方法或者疑问和意见欢迎大家提出来一起讨论!