Spring自动装配
Spring 装配机制
- 在xml中显式配置;
- 在java中显式配置;
- 隐式的bean发现机制和自动装配。
此文主要讲述第三种自动化的装配bean
自动装配的实现角度:组件扫描和自动装配
推荐不使用自动装配xml配置 , 而使用注解 !
搭建测试环境
新建项目,新建实体类Cat 和 Dog,并且这两个类都有动物叫的方法
public class Cat {
public void shout() {
System.out.println("miao~");
}
}
public class Dog {
public void shout() {
System.out.println("wang~");
}
}
新建用户类User
public class User {
private Cat cat;
private Dog dog;
private String str;
}
编写spring配置文件 beans.xml
<?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.xsd">
<bean id="dog" class="com.baicha.pojo.Dog"/>
<bean id="cat" class="com.baicha.pojo.Cat"/>
<bean id="user" class="com.baicha.pojo.User">
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
<property name="str" value="baihca"/>
</bean>
</beans>
测试
public class MyTest {
@Test
public void testMethodAutowire() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) context.getBean("user");
user.getCat().shout();
user.getDog().shout();
}
}
测试能正常输出 wang和miao
byName配置 autowire byName (按名称自动装配)
采用自动装配将避免这些错误,并且使配置简单化。
修改上面的配置文件 增加一个属性 autowire=“byName”
<bean id="user" class="com.baicha.pojo.User" autowire="byName">
<property name="str" value="baicha"/>
</bean>
再次测试,结果依旧成功输出!
我们将 cat 的bean id修改为 cat111;
再次测试报空指针异常,因为按照byName规则是找不到对应的setCat111方法,真正的setCat就没执行,对象也没有进行初始化,所以调用时就会报空指针异常;
autowire byName的规则
-
查找其类中的所有set方法名,例如setCat 规则将set去掉并且获得Cat的首字母小写的字符串,即cat
-
在Spring容器中查找是否有此字符串名称id的对象
-
如果有就进行注入,没有就报空指针java.lang.NullPointerException
byType 配置(autowire byType (按类型自动装配))
使用autowire byType首先需要保证:**同一类型的对象,在spring容器中唯一。**如果不唯一,会报不唯一的异常(NoUniqueBeanDefinitionException)。
- 将上面配置文件的user的bean修改为autowire=“byType”
- 测试,能正常运行输出
- 再注册一个cat的bean
<bean id="dog" class="com.baicha.pojo.Dog"/>
<bean id="cat" class="com.baicha.pojo.Cat"/>
<bean id="cat2" class="com.baicha.pojo.Cat"/>
<bean id="user" class="com.baicha.pojo.User" autowire="byType">
<property name="str" value="baicha"/>
</bean>
-
测试,报错:NoUniqueBeanDefinitionException
-
删除cat2的bean(其次也可以将cat的bean名称改掉,甚至可以吧id属性去掉,不会影响测试结果)
-
测试成功,能正常运行(因为是按照类型装配,并不会报错)