Bean的自动装配

一:自动装配说明

  • 自动装配是使用spring满足bean依赖的一种方法 。
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean有三种装配机制:

在xml中显式配置;
在java中显式配置;
隐式的bean发现机制和自动装配。

Spring的自动装配需要从两个操作实现:

组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
自动装配(autowiring):spring自动满足bean之间的依赖(IoC/DI);

不推荐使用自动装配xml配置 , 而使用注解

二:xml方式自动装配(不推荐)

实体类:

public class Books {
    public void show(){
        System.out.println("读四大名著");
    }
}
public class Hobbies {
    public void show(){
        System.out.println("培养兴趣爱好");
    }
}
public class Pepole {
    private String name;
    private Books books;
    private Hobbies hobbies;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Books getBooks() {
        return books;
    }

    public void setBooks(Books books) {
        this.books = books;
    }

    public Hobbies getHobbies() {
        return hobbies;
    }

    public void setHobbies(Hobbies hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "Pepole{" +
                "name='" + name + '\'' +
                ", books=" + books +
                ", hobbies=" + hobbies +
                '}';
    }
}

配置文件:

  1. autowire byName (按名称自动装配)

byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid(通过id匹配)

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

    <bean id="books" class="com.lmy.pojo.Books"/>
    <bean id="hobbies" class="com.lmy.pojo.Hobbies"/>

    <bean id="pepole" class="com.lmy.pojo.Pepole" autowire="byName">
        <property name="name" value="zhangSan"/>
    </bean>
</beans>

总结:
当一个bean节点带有 autowire byName的属性时:
将查找其类中所有的set方法名,例如setBooks,获得将set去掉并且首字母小写的字符串,即books。去spring容器中寻找是否有此字符串名称id的对象。如果有,就取出注入;如果没有,就报空指针异常。

  1. autowire byType (按类型自动装配)

byType : 会自动在容器上下文中查找,和自己对象属性类型相同的bean(通过class匹配)

使用autowire byType首先需要保证:同一类型的bean对象,在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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="books" class="com.lmy.pojo.Books"/>
    <bean id="hobbies" class="com.lmy.pojo.Hobbies"/>

    <bean id="pepole" class="com.lmy.pojo.Pepole" autowire="byType">
        <property name="name" value="zhangSan"/>
    </bean>
</beans>

测试:

public class MyTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Pepole pepole = context.getBean("pepole", Pepole.class);
        pepole.getBooks().show();
        pepole.getHobbies().show();
    }
}

输出:

读四大名著
培养兴趣爱好

Process finished with exit code 0

结论:

  • byname的时候,要保证所有bean的id唯一,且这个bean需要和自动注入的属性的set方法的值一致
  • bytype的时候,要保证所有bean的class唯一,且这个bean需要和自动注入的属性的类型一致

二:使用注解

实体类:

public class Books {
    public void show(){
        System.out.println("读四大名著");
    }
}
public class Hobbies {
    public void show(){
        System.out.println("培养兴趣爱好");
    }
}
public class Pepole {
    private String name;
    @Autowired
    @Qualifier("books1")
    private Books books;
    @Autowired
    private Hobbies hobbies;

    public Books getBooks() {
        return books;
    }

    public Hobbies getHobbies() {
        return hobbies;
    }

    @Override
    public String toString() {
        return "Pepole{" +
                "name='" + name + '\'' +
                ", books=" + books +
                ", hobbies=" + hobbies +
                '}';
    }
}

配置文件:

<?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
        http://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="books2" class="com.lmy.pojo.Books"/>
    <bean id="books1" class="com.lmy.pojo.Books"/>
    <bean id="hobbies" class="com.lmy.pojo.Hobbies"/>
    <bean id="pepole" class="com.lmy.pojo.Pepole"/>

</beans>

注意: 在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

开启属性注解支持!

<context:annotation-config/>

测试类:

public class MyTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Pepole pepole = context.getBean("pepole", Pepole.class);
        pepole.getBooks().show();
        pepole.getHobbies().show();
    }
}

1)使用 @Autowired 自动装配

@Autowired是Spring提供的注解,用于自动装配
装配方式:

  • 按类型装配(默认使用的装配方式)。
  • 按名称装配(结合@Qualifier注解使用)。

注解属性:
required:默认值true。值为true时,表示必须注入,如bean不存在则会报错;值为false时,表示bean存在就注入,不存在则不注入。

作用范围:@Autowired的作用范围:成员变量、构造器、方法、参数。

  1. 成员变量
@Service
public class UserService {

    @Autowired
    private IUser user;
}
  1. 构造器:构造器上使用Autowired注解,实际上还是使用了成员变量装配的方式,并非构造器装配。
@Service
public class UserService {

    private IUser user;

    @Autowired
    public UserService(IUser user) {
        this.user = user;
    }
}
  1. 方法:Spring会在项目启动的过程中,自动调用一次@Autowired注解的方法,我们可以在该方法做一些初始化的工作。
@Service
public class UserService {

    @Autowired
    public void test(IUser user) {
       user.test();
    }
}
  1. 参数:在非静态方法的入参上加Autowired注解
@Service
public class UserService {

    public void test(@Autowired IUser user) {
       user.test();
    }
}

@Qualifier的使用:通过@Autowired和@Qualifier的结合使用可以按名称装配。

    @Autowired
    @Qualifier("books1")
    private Books books;

配置:

    <bean id="books2" class="com.lmy.pojo.Books"/>
    <bean id="books1" class="com.lmy.pojo.Books"/>
    <bean id="hobbies" class="com.lmy.pojo.Hobbies"/>

实体类:

    @Autowired
    @Qualifier("books1")
    private Books books;
    @Autowired
    private Hobbies hobbies;

输出:

读四大名著
培养兴趣爱好

Process finished with exit code 0

2)使用@Resource自动装配

@Resource是JDK自带的注解,用于自动装配。

@Resource默认按照名称自动注入

  • 既没指定name,也没指定type,自动按照名称装配(当注解写在字段上时,默认取字段名,当注解写在setter方法上时,默认取属性名进行装配。);如果没有匹配,则退而按照类型装配,找不到则抛出异常。

  • 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

  • 如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

  • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

注解属性
Resource注解的主要属性:

  • name:指定需注入的bean的名称
  • type: 指定需注入的bean的类型

作用范围
@Resource的作用范围:成员变量、方法。

  1. 成员变量
@Service
public class UserService {

    @Resource
    private IUser user;
}
  1. 方法
@Service
public class UserService {

    @Resource
    public void test(IUser user) {
        user.test();
    }
}

@Resource指定按type自动装配:

    @Resource(type = Books.class)
    private Books books;

@Resource指定按name自动装配:

    @Resource(name = "books")
    private Books books;

@Autowired与@Resource对比:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值