SPR5: Bean的自动装配

5.1 简介

​ 在Spring种,通过容器进行对象的加载。属性装配可以xml手动录入(构造器,setter(),命名空间),也可以使用java进行装配,但是在bean之间的属性引用上,可以使用Spring的自动装配。

5.2 autowire属性

5.2.1 环境

Computer.java:

package com.yun.pojo;

public class Computer {
    public void operation(){
        System.out.println("电脑开机");
    }
}

Phone.java:

package com.yun.pojo;

public class Phone {
    public void operation(){
        System.out.println("手机开机");
    }
}

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

        <bean id="computer" class="com.yun.pojo.Computer"/>
        <bean id="phone" class="com.yun.pojo.Phone"/>
</beans>

测试接口:

package com.yun;

import com.yun.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    @Test
    public void UserTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        user.getComputer().operation();
        user.getPhone().operation();
    }
}

5.2.1 ByName

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

        <bean id="computer" class="com.yun.pojo.Computer"/>
        <bean id="phone" class="com.yun.pojo.Phone"/>

        <bean id="user" class="com.yun.pojo.User" autowire="byName"/>
</beans>

提示: user’Bean 会自动按照实体类名字,进行匹配,并进行装配compuer与phone。

输出结果:

电脑开机
手机开机

5.2.2 ByType

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

        <bean id="computer" class="com.yun.pojo.Computer"/>
        <bean id="phone" class="com.yun.pojo.Phone"/>

        <bean id="user" class="com.yun.pojo.User" autowire="byType"/>
</beans>

提示: user’Bean 在被Spring容器加载时,会根据实体类的属性类型,对对象引用属性进行装配。例如Computer类,则会查找class为 com.yun.pojo.Computer 的bean,弊端则是一个类只能拥有一个bean。

输出结果:

电脑开机
手机开机

5.3 注解实现自动装配

5.3.1 导入约束

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">

5.3.2 导入支持

<context:annotation-config/>

文件概览


<?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/>

</beans>

5.3.3 Autowired注解的使用

applicationCotext.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"
       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="computer" class="com.yun.pojo.Computer"/>
        <bean id="phone" class="com.yun.pojo.Phone"/>

        <bean id="user" class="com.yun.pojo.User"/>
</beans>

提示: 在导入约束与支持之后,在Spring配置文件中,将实体类进行注册。并且不用指定自动装配的方式,因为将实体类的属性装配交给注解,并在实体类内部实现。

User.java:

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class User {
    public Computer getComputer() {
        return computer;
    }

    public void setComputer(Computer computer) {
        this.computer = computer;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    @Autowired
    private Computer computer;
    @Autowired
    private Phone phone;
}

总结: 通过测试接口,依旧可以达到autowire属性的功能。Autowired注解在底层实现,依靠的是byType方式。如果一个实体类中,有两个同类型的属性,而Spring中只注册了一个该类型的bean,那么程序依旧执行成功;但如果Spring中注册了两个或多个同样类型的bean,那么程序便会报 Could not autowire. There is more than one bean of ‘Computer’ type 的错误。为了解决这一问题,Spring提供了 @Qualifier 注解。

5.3.4 注解Qualifier

User.java:

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class User {
    public Computer getComputer() {
        return computer;
    }

    public void setComputer(Computer computer) {
        this.computer = computer;
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    @Autowired
    private Computer computer;
    @Autowired
    private Phone phone;
    
    @Autowired
    @Qualifier(value = "computer")
    private Computer computer1;

    public Computer getComputer1() {
        return computer1;
    }

    public void setComputer1(Computer computer1) {
        this.computer1 = computer1;
    }
}

applicationContext.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"
       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="gsgdfsgf" class="com.yun.pojo.Computer"/>
        <bean id="computer" class="com.yun.pojo.Computer"/>
        <bean id="phone" class="com.yun.pojo.Phone"/>

        <bean id="user" class="com.yun.pojo.User"/>
</beans>

提示: 上述代码实现了Spring配置文件中有两个同类型的bean,然后在实体类中使用自动装配注解时,添加了 Qualifier 注解,并为它指定了其余的bean id。

5.3.5 属性装配空值

  • required

    @Autowired(required = false)
    
  • Nullable

    @Autowired
        public void setPhone(@Nullable Phone phone) {
            this.phone = phone;
        }
    

    提示: 这里可以看出,Autowird 并不仅仅用于字段上面,还可以用于setter()上面。而Nullable的作用是,可以设置属性值为空,但具体实例不好举。

5.3.6 Resource注解

User.java:

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.Nullable;

import javax.annotation.Resource;

public class User {
    public Computer getComputer() {
        return computer;
    }

    public void setComputer(Computer computer) {
        this.computer = computer;
    }

    public Phone getPhone() {
        return phone;
    }

    @Autowired
    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    @Autowired
    private Computer computer;

    private Phone phone;
    
    @Resource(name = "computer")
    private Computer computer1;

    public Computer getComputer1() {
        return computer1;
    }

    public void setComputer1(Computer computer1) {
        this.computer1 = computer1;
    }
}

提示 Resource 注解是java提供的注解,并且功能比 autowire更为强大,它自动装配的方式先byName如果不行,然后byType。但是,Spring的bean一般都是单例模式,因此,使用并不多。


写在最后,所谓的装配,其实就是当我们把实体类注册到容器中,我们需要给实体类的属性赋值。而目前为止,像对象引用这类的属性,则可以给它们指定容器中的bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值