Version: Next

Bean自动装配

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

在Spring中有三种装配的方式

  1. 在xml中显示配置
  2. 在java中显示配置
  3. 隐式的自动装配(重要)

1. 测试环境搭建

新建maven模块,spring-05-autowired

  • 实体类

    @Data
    @NoArgsConstructor
    public class Dog {
    public void shout(){
    System.out.println("汪");
    }
    }
    @Data
    @NoArgsConstructor
    public class Cat {
    public void shout(){
    System.out.println("喵");
    }
    }
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class People {
    private Cat cat;
    private Dog dog;
    private String name;
    }
  • beans.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="cat" class="com.bsx.pojo.Cat"/>
    <bean id="dog" class="com.bsx.pojo.Dog"/>
    <bean id="people" class="com.bsx.pojo.People">
    <property name="name" value="我的名字"/>
    <property name="dog" ref="dog"/>
    <property name="cat" ref="cat"/>
    </bean>
    </beans>
  • 测试

    @Test
    public void testEnv(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    People people = context.getBean("people", People.class);
    people.getCat().shout();
    people.getDog().shout();
    }

2. 自动装配(自动注入)

  1. byName通过名字匹配 会自动在容器中查找和自己对象set方法后面对应的bean id

    <bean id="cat" class="com.bsx.pojo.Cat" />
    <bean id="dog" class="com.bsx.pojo.Dog" />
    <bean id="people" class="com.bsx.pojo.People" autowire="byName">
    <property name="name" value="我的名字"/>
    </bean>
  2. byType按照类型匹配 如果有多个类型一样的bean,直接报错

    <bean id="cat" class="com.bsx.pojo.Cat"/>
    <bean id="dog" class="com.bsx.pojo.Dog"/>
    <bean id="people" class="com.bsx.pojo.People" autowire="byType">
    <property name="name" value="我的名字"/>
    </bean>
  • byName时,需要保证所有bean的id唯一,并且bean需要和自动注入的set方法的值一致
  • byType,需要保证所有的bean类型唯一,并且bean需要和自动注入的属性类型一致

3. 注解自动装配

jdk1.5支持的注解, Spring 2.5支持注解

要使用注解须知:

  1. 导入约束

    xmlns:context="http://www.springframework.org/schema/context"
  2. 配置注解的支持

    • 可以开启全局注解

      <context:annotation-config/>
    • 可以指定扫描某个包下的注解

      <context:component-scan base-package="com.bsx.pojo"/>

@Autowired

  1. 先按类型自动注入

  2. 多个类型相同,当bean id和 属性名相同时,可以自动注入

  3. 注解通过反射创建对象因此不需要set方法,前提是自动注入的属性已经在IoC容器中存在,且bean id 等于 属性名

  4. 可以在属性上使用,也可以在set方法上使用

  • beans.xml
<context:annotation-config/>
<bean id="cat" class="com.bsx.pojo.Cat"/>
<bean id="dog" class="com.bsx.pojo.Dog"/>
<bean id="people" class="com.bsx.pojo.People"/>
  • People.java
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
}

跑一下上面的测试类,正常。

  • 科普

    • @Nullable: 标记某个字段值可以为null

    • @Autowired(required == false) 默认为true,如果设置为false说明这个对象可以为null

      public @interface Autowired {
      boolean required() default true;
      }

@Qualifier

  1. 配合@Autowired使用,可以指定按名称注入
  2. 里面有一个value值用来指定名称
  • beans.xml

    <context:annotation-config/>
    <bean id="cat222" class="com.bsx.pojo.Cat"/>
    <bean id="cat111" class="com.bsx.pojo.Cat"/>
    <bean id="dog" class="com.bsx.pojo.Dog"/>
    <bean id="people" class="com.bsx.pojo.People"/>
  • People.java

    public class People {
    @Autowired
    @Qualifier("cat222")
    private Cat cat; // 把容器里的cat222对象注入到People里的cat属性里
    @Autowired
    private Dog dog;
    private String name;
    }

@Resource (JDK)

这是一个Java自己的注解,也可以实现自动注入。 用name属性可以指定属性名

  • beans.xml

    <bean id="cat222" class="com.bsx.pojo.Cat"/>
    <bean id="cat111" class="com.bsx.pojo.Cat"/>
    <bean id="dog" class="com.bsx.pojo.Dog"/>
    <bean id="people" class="com.bsx.pojo.People"/>
  • People.java

    public class People {
    @Resource(name = "cat111")
    private Cat cat;
    @Resource
    private Dog dog;
    private String name;
    }