一、设值注入(属性的setter访问器)
dao:
package firstIOC;
public class UserDao {
public void say(){
System.out.println("I am UserDao");
}
}
service:
package firstIOC;
public class UserService {
private UserDao userDao;
//userDao属性的setter方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void print(){
System.out.println("我是UserService");
userDao.say();
}
}
bean.xml
<bean id="userDao" class="firstIOC.UserDao"/>
<bean id="userService" class="firstIOC.UserService" >
<property name="userDao" ref="userDao"/>
</bean>
TEST
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
UserService service = (UserService) app.getBean("userService");
service.print();
}
输出
设值注入特点:通过setter访问器注入,灵活性好,但setter方法较多,通过Java虚拟机默认提供的无参构造方法实例化。
二、构造注入
dao不变
service:
package secondIOC;
public class UserService {
private UserDao userDao;
public UserService() {
}
//构造方法
public UserService(UserDao userDao) {
this.userDao=userDao;
}
public void print(){
System.out.println("我是UserService");
userDao.say();
}
}
此处service跟上面的service的不同在于 一个是属性的setter方法,一个是带参数的构造方法
bean:
<bean id="userDao" class="secondIOC.UserDao"/>
<bean id="userService" class="secondIOC.UserService">
<constructor-arg>
<ref bean="userDao"/>
</constructor-arg>
</bean>
此处bean使用了
<constructor-arg>元素
一个<constructor-arg>代表构造方法的一个参数,不区分顺序
可以通过index属性指定参数的位置,从0开始,还可以设置type属性指定参数数据类型
<constructor-arg index='3' type='String'><ref bean="password"> </constructor-arg> 表示给第四个String类型的参数赋值
构造注入特点:通过构造函数注入,灵活性差,仅仅靠重载限制太多,通过匹配的构造方法实例化。
三、p命名空间注入
service:
package thirdIOC;
public class UserService {
private UserDao userDao;
public void print(){
System.out.println("我是UserService");
userDao.say();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
bean.xml:
<bean id="userDao" class="thirdIOC.UserDao"/>
<bean id="userService" class="thirdIOC.UserService" p:userDao-ref="userDao" />
bean.xml需要多引入 xmlns:p="http://www.springframework.org/schema/p"
对于基本数据类型、字符串等属性:p:属性名="属性值"
对于引用bean:p:属性名-ref="bean id"
p命名空间注入跟setter注入原理实际一样,区别在于bean
四:c命名空间注入
service:
package fourthIOC;
public class UserService {
private UserDao userDao;
public UserService() {
}
//构造方法
public UserService(UserDao userDao) {
this.userDao=userDao;
}
public void print(){
System.out.println("我是UserService");
userDao.say();
}
}
bean.xml:
<bean id="userDao" class="fourthIOC.UserDao"/>
<!-- c:属性名="属性值"
c:属性名-ref="bean id"
<bean id="userService" class="fourthIOC.UserService" c:userDao-ref="userDao" />
-->
<!-- c:_参数下标="属性值"
c:_参数下标-ref="bean id" -->
<bean id="userService" class="fourthIOC.UserService" c:_0-ref="userDao" />
bean.xml头文件需要引入 xmlns:c="http://www.springframework.org/schema/c"
c命名空间注入跟构造注入原理实际一样,区别在于bean
五、自动注入autowire
service:
package fifthIOC;
public class UserService {
private UserDao userDao;
//setter方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void print(){
System.out.println("我是UserService");
userDao.say();
}
}
bean.xml:
<bean id="userDao" class="fifthIOC.UserDao"/>
<bean id="userService" class="fifthIOC.UserService" autowire="byName"/>
或者可以配置全局自动注入:在头文件中加上default-autowire="byName"
no 不使用自动装配,必须通过ref元素指定依赖,默认设置。
byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。
byType 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异
常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生,也可以通过设置
dependency-check="objects"让Spring抛出异常。
constructor 与byType方式类似,不同之处在于它应用于构造器参数。如
果容器中没有找到与构造器参数类型一致的bean,那么抛出异常
当然也可以设置某个bean自动装配失效
将<bean/>元素的autowire-candidate属性设置为false,这样容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其它bean自动装配的候选者,但是该bean本身还是可以使用自动装配来注入其它bean的。
--------------------------------------
五种方式都是基于xml手动方式配置bean的,当然还有使用扫描包+@Autowired、Java的配置方式(SpringConfig)@Bean配置