Spring03:装配

1 Spring 的装配机制

  1. 在 xml 中显式配置;

  2. 在 java 中显式配置;

  3. 隐式的 bean发现机制和自动装配

之前我们常用的便是第一种,在 xml 中显式配置,比如上一章中的依赖注入,接下来将介绍隐式的 bean发现机制和自动装配。

2 自动装配

根据需求来理解。

确定需求如下:在实验室类(Lab)中装配两个两个同学类(Sharm、Nola),使得在测试的时候可以直接通过 Lab 对象来输出同学的方法。

接下来对比 xml 手动装配和隐式的自动装配的区别。

2.1 xml 手动装配

1)创建两个同学类(Sharm、Nola)

public class Sharm {
    public void show(){
        System.out.println("My name is Sharm, do you know.");
    }
}
public class Nola {
    public void show(){
        System.out.println("My name is Nola, do you know.");
    }
}

2)创建一个包含(Sharm、Nola)属性的实验室类(Lab)

public class Lab {
    public Sharm sharm;
    public Nola nola;
    public String admin;

    public Lab() {
    }

    public Lab(Sharm sharm, Nola nola, String admin) {
        this.sharm = sharm;
        this.nola = nola;
        this.admin = admin;
    }

    public Sharm getSharm() {
        return sharm;
    }

    public void setSharm(Sharm sharm) {
        this.sharm = sharm;
    }

    public Nola getNola() {
        return nola;
    }

    public void setNola(Nola nola) {
        this.nola = nola;
    }

    public String getAdmin() {
        return admin;
    }

    public void setAdmin(String admin) {
        this.admin = admin;
    }
}

3)编写 Spring 配置文件

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="sharm" class="sharm.autowire.Sharm"/>
    <bean id="nola" class="sharm.autowire.Nola"/>

    <bean id="lab" class="sharm.autowire.Lab">
        <property name="admin" value="Jalu"/>
        <property name="sharm" ref="sharm"/>
        <property name="nola" ref="nola"/>
    </bean>

</beans>

4)测试

public class AutowireTest {
    @Test
    public void test(){
        // 固定写法
        ApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
        // 得到对象,其中参数为对象名
        Lab lab = context.getBean("lab", Lab.class);
        // 开始使用对应同学类的方法
        lab.sharm.show();
        lab.nola.show();
    }
}

2.2 隐式的自动装配

两种自动装配的属性:

属性名 作用
byName 按照属性名自动装配,使用该属性后,会自动在容器上下文中查找和自己对象 setter 方法后面的值相同的 bean id。如果有,就取出注入,如果没有,就报(NullPointerException)空指针异常。
byType 按照类型自动装配,使用该属性后,会自动在容器上下文中查找和自己对象类型相同的 bean。同时,在 Spring 容器中,同一类型的对象必须要唯一。

2.2.1 byName

保持三个实体类不变,修改 Spring 配置文件如下:

    <bean id="sharm" class="sharm.autowire.Sharm"/>
    <!-- 因为是按照 bean id 名来取对应的 bean 的,所以如果修改 id 值,则会导致自动注入失败-->
    <bean id="nola_fail" class="sharm.autowire.Nola"/>
<!-- 所以必须使用下一种方式-->
<!--    <bean id="nola" class="sharm.autowire.Nola"/>-->

<!-- 使用 byName 或者 byType 只需要修改 bean 标签的 autowire 的值 -->
    <bean id="lab" class="sharm.autowire.Lab" autowire="byName">
        <property name="admin" value="Jalu"/>
    </bean>

2.2.2 byType

    <bean id="sharm" class="sharm.autowire.Sharm"/>
    <!-- 因为是按照 bean 的类型来获取对应的 bean 的,所以如果就算 id 正确,但类错误,也会导致自动注入失败-->
    <bean id="nola" class="sharm.autowire.Sharm"/>
<!-- 所以必须使用下一种方式-->
<!--    <bean id="nola" class="sharm.autowire.Nola"/>-->

<!-- 使用 byName 或者 byType 只需要修改 bean 标签的 autowire 的值 -->
    <bean id="lab" class="sharm.autowire.Lab" autowire="byType">
        <property name="admin" value="Jalu"/>
    </bean>

3 使用注解实现自动装配

3.1 简介

注释名 配置 位置 作用
@Autowired 需要加入配置文件以及导入 jar 包 可以写在字段上,或写在setter方法上 根据类型自动装配的,如果想使用 byName 装配,则需要另外加上 @Qualifier 注解
@Resource 不需要加入配置文件,需要导入 jar 包 可以写在字段上,或写在setter方法上 优先使用指定的name属性进行装配,其次使用 byName 装配,最后使用 byType 装配,如果都不成功,则报异常

3.2 @Autowired 自动装配

1)导入 spring-aop 包

2)修改 Spring 配置文件

<?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
        https://www.springframework.org/schema/beans/spring-beans.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
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>
</beans>

3)修改实验室类(Lab)

在字段或者 setter 方法加上 @Autowired 注解

public class Lab {
    @Autowired
    public Sharm sharm;
    @Autowired
    // @Autowired(required = false) 字段不必须存对象
    public Nola nola;
    public String admin;
    ……
}

4)修改 Spring 配置文件

<?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
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="nola" class="sharm.autowire.Nola"/>
    <bean id="sharm" class="sharm.autowire.Sharm"/>
    <bean id="lab" class="sharm.autowire.Lab"/>
</beans>

5)当容器中包含多个 Sharm 对象时

因为 @Autowired 是根据类型自动装配的,如果当容器中包含多个 Sharm 对象时,则可以加上 @Qualifier 来根据 byName 的方式自动装配。

public class Lab {
    @Autowired
    @Qualifier(value = "cheatSharm")
    public Sharm sharm;
    @Autowired
    public Nola nola;
    public String admin;
    ……
}
<bean id="nola" class="sharm.autowire.Nola"/>
<bean id="sharm" class="sharm.autowire.Sharm"/>
<bean id="cheatSharm" class="sharm.autowire.Sharm"/>
<bean id="lab" class="sharm.autowire.Lab"/>

3.3 @Resource 自动装配

1)导入 jar 包(加入 Maven 依赖)

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>jsr250-api</artifactId>
    <version>1.0</version>
</dependency>

2)修改实验室(Lab)实体类

public class Lab {
    @Resource(name="cheatSharm")
    public Sharm sharm;
    @Resource(name="nola")
    public Nola nola;
    public String admin;
    ……
}

3)对应的 Spring 配置文件

<bean id="nola" class="sharm.autowire.Nola"/>
<bean id="sharm" class="sharm.autowire.Sharm"/>
<bean id="cheatSharm" class="sharm.autowire.Sharm"/>
<bean id="lab" class="sharm.autowire.Lab">
    <property name="admin" value="Luma"/>
</bean>

4)OK

上一篇:sql-lab:Less21-22(后续接着更新)


下一篇:jupyter lab中使用anaconda创建的虚拟环境