【6】Spring5中Bean的自动装配
7、Bean的自动装配
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式:
- 在xml中显式配置
- 在java中显式配置
- 隐式的自动装配bean【重要】
7.1、测试
环境搭建:一个人有两个宠物
person类,get、set等方法省略
public class Person {
private String name;
private Dog dog;
private Cat cat;
}
dog类
public class Dog {
public void shout(){
System.out.println("wangwangwang!");
}
}
cat类
public class Cat {
public void shout(){
System.out.println("miaomiaomiao!");
}
}
7.2、byName自动装配
<bean id="cat" class="com.kuber.pojo.Cat"/>
<bean id="dog" class="com.kuber.pojo.Dog"/>
<!--
byName:会自动在容器上下文中查找,这个是将set方法的名称去掉开头的set后全部小写得到的,然后和引入的beanid进行匹配
-->
<bean id="person" class="com.kuber.pojo.Person" autowire="byName">
<property name="name" value="工藤胖虎"/>
<!--<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>-->
</bean>
7.3、byType自动装配
<bean class="com.kuber.pojo.Cat"/>
<bean class="com.kuber.pojo.Dog"/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean(class)进行匹配(因此可以不需要beanid)
-->
<bean id="person" class="com.kuber.pojo.Person" autowire="byType">
<property name="name" value="工藤胖虎"/>
<!--<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>-->
</bean>
7.4、小结
- byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的set方法名去掉set后的值首字母小写后一致
- byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性类型一直
7.5、使用注解实现自动装配
-
导入约束
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> </beans>
-
使用配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="cat" class="com.kuber.pojo.Cat"/> <bean id="dog" class="com.kuber.pojo.Dog"/> <!-- byName:会自动在容器上下文中查找,这个是将set方法的名称去掉开头的set后全部小写得到的,然后和引入的beanid进行匹配 byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean(class)进行匹配(因此可以不需要beanid) --> <bean id="person" class="com.kuber.pojo.Person"> <property name="name" value="工藤胖虎"/> <!--<property name="cat" ref="cat"/> <property name="dog" ref="dog"/>--> </bean> </beans>
@Autowired注解
直接在属性上使用即可,也可以在set方式上使用
使用@Autowired
后可以不用编写set方法了,前提是你这个自动装配的属性IOC(Spring)容器中存在,且符合类型byType(Autowired默认按类型进行匹配,若未找到再按byName进行匹配)
扩展
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)(和beanid进行匹配)去配合@Autowired的使用,指定一个唯一的bean对象注入
@Resource注解(在jdk11被移除了)
public class Person {
private String name;
@Resource
private Dog dog;
@Resource
private Cat cat;
}
@Resource默认按照byName进行自动装配,未找到则按byType进行装配,也可以指定name和beanid进行匹配
<bean id="cat1" class="com.kuber.pojo.Cat"/>
<bean id="cat123" class="com.kuber.pojo.Cat"/>
<bean id="dog1" class="com.kuber.pojo.Dog"/>
public class Person {
private String name;
@Resource
private Dog dog;
@Resource(name = "cat123")
private Cat cat;
}
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person.getName());
person.getCat().shout();
person.getDog().shout();
}
此时若没指定name则测试报错,因为byName找不到id为cat的,再按byType找则有多个,所以会抛NoUniqueBeanDefinitionException异常。指定name为"cat123"后则正常。
小结:
@Autowired和@Resource的区别
-
都是用来自动装配的,都可以放在字段上,并且使用之后不再需要set方法
-
@Autowired默认通过byType实现,而且要求这个对象必须存在,类型未找到或有多个同类型bean再按照byName匹配,再未找到则报错,但是可以使用@Qualifier(value = “xxx”)(和beanid进行匹配)去配合@Autowired的使用,指定一个唯一的bean对象注入,【常用】
-
@Resource默认按照byName进行自动装配,未找到则按byType进行装配,也可以指定name和beanid进行匹配【常用】
上一篇: Spring学习笔记