欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【6】Spring5中Bean的自动装配

程序员文章站 2022-07-15 10:26:51
...

7、Bean的自动装配

  • 自动装配是Spring满足bean依赖的一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式:

  1. 在xml中显式配置
  2. 在java中显式配置
  3. 隐式的自动装配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、使用注解实现自动装配

  1. 导入约束

    <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>
    
  2. 使用配置

    <?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 5 spring 5