Spring的Bean自动装配(含注解)

自动装配相对应的就是手动装配,在讲自动装配前先介绍手动装配,就是要自己给定属性,然后赋值

1. 手动装配

1.1 使用场景

有一个Person类,这个类中聚合了一个Cat类和Dog类。

public class Person {
    private Dog dog;
    private Cat cat;
    private String name;
    // getter/setter...
}

那么在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 http://www.springframework.org/schema/beans/spring-beans.xsd">
       
    <bean id="cat" class="com.zzw.pojo.Cat" />
    <bean id="dog" class="com.zzw.pojo.Dog" />
    <bean id="people" class="com.zzw.pojo.Person">
        <property name="name" value="Bob" />
        <property name="cat" ref="cat" />
        <property name="dog" ref="dog" />
    </bean>
    
</beans>

1.2 缺点

可以看到所谓手动注入是指在xml中采用硬编码的方式来配置注入的对象,比如通过构造器注入或者set方法注入,这些注入的方式都存在不足:

  • 如果需要注入的对象比较多,比如Person类中有几十个属性,那么上面的property属性是不是需要写几十个,此时配置文件代码量暴增
  • 如果Person类中新增或者删除了一些依赖,还需要手动去调整bean xml中的依赖配置信息,否则会报错
  • 总的来说就是不利于维护和扩展

2. 自动装配

自动装配的意义和p/c命名空间的使用一样,为了简化代码。自动注入是采用约定大约配置的方式来实现的,程序和spring容器之间约定好,遵守某一种都认同的规则,来实现自动注入。

自动装配方式:1. byType 2. byName 3. constructor 4. default
<bean id="" class="" autowire="byType|byName|constructor|default" />

2.1 ByName自动装配

给bean添加一个属性autowire="byName"

    <bean id="cat" class="com.zzw.pojo.Cat" />
    <bean id="dog" class="com.zzw.pojo.Dog" />
    <bean id="people" class="com.zzw.pojo.Person" autowire="byName">
    	<!-- 使用autowire之后,就无需再为Person装配Cat和Dog属性 -->
        <property name="name" value="Bob" />
    </bean>

2.1.1 注意点

  1. 保证所有bean的id唯一
  2. 在容器上下文寻找,对象set方法后面的值必须和对应的beanid一样,即Dog的bean id必须是dog,因为Person里的setDog()里是"Dog",换成小写就是"dog"。
  3. 未找到对应名称的bean对象则set方法不进行注入,并不会报错(如果报了可能是因为测试代码中用到了注入失败的bean对象)

2.2 ByType自动装配

给bean添加一个属性autowire="byType"

	<bean id="cat" class="com.zzw.pojo.Cat" />
    <bean class="com.zzw.pojo.Dog" />
    <bean id="people" class="com.zzw.pojo.Person" autowire="byType">
        <property name="name" value="Bob" />
    </bean>

2.2.1 注意点

  1. 保证所有bean的class唯一!按照类型自动装配的时候,如果按照类型找到了多个符合条件的bean,系统会报错。
  2. 在容器上下文寻找,对象set方法的类型必须和对应的bean的类型一样
  3. 使用ByType,bean可以没有id

3. 使用注解实现自动装配

大部分情况下,都会使用注解进行开发而非xml,因为xml还是太麻烦了。
使用注解:

  1. 导入约束: xmlns:context="http://www.springframework.org/schema/context"
  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>

@Autowire,直接在属性上使用即可,也可以在set方法上使用。对属性使用了@Autowire后,set方法都可以直接省略(反射机制),但get方法还是要写,前提是:这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName

@Autowire默认先使用byType,不匹配再使用byName

Java代码:

public class Person {
    @Autowired	// 使用该注解后,会自动去Spring的IOC容器中寻找相应"类型"的已被注册的bean
    private Dog dog;
    @Autowired
    private Cat cat;
    private String name;
    ...
}

beans.xml代码:

<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.zzw.pojo.Cat" />
    <bean id="dog" class="com.zzw.pojo.Dog" />
    <bean id="people" class="com.zzw.pojo.Person" />

</beans>

测试代码:

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Person people = applicationContext.getBean("people", Person.class);
        people.getCat().shout();
        people.getDog().shout();
    }
}

4. @Qualifier

@Qualifier,可以指定字段在xml配置文件中的id,当xml中有多个同一对象(有着不同id),这个注解比较好用。换言之,这是类型重复了,使用@Qualifier来指定是一个具体bean的id。@Qualifier注解通常和@Autowire一同使用。

Bean:

public class Person {
    @Autowired
    private Dog dog;
    
    @Autowired
    @Qualifier(value = "cat123")
    private Cat cat;
    
    private String name;
    ...
}

beans.xml文件:

    <bean id="cat" class="com.zzw.pojo.Cat" />
    <bean id="dog" class="com.zzw.pojo.Dog" />
    <bean id="cat123" class="com.zzw.pojo.Cat" />
    <bean id="people" class="com.zzw.pojo.Person" />

注意:

  1. @Qualifier相对应的类型必须匹配

5. @Resource

@Resource,Java的注解,效果和@Aotuwire类似,默认byNamebyType。这个注解使用频率低,主要还是@Autowire

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值