Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】

自动装配

1、歧义性

我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器中注册了,要怎么去区分对哪一个Bean进行注入呢?

如下情况,若用@Autowired的方式按类型注入,IOC容器就不知道应该注入哪个了:

<bean name="source1" class="pojo.Source">
    <property name="fruit" value="橙子"/>
    <property name="sugar" value="多糖"/>
    <property name="size" value="超大杯"/>
</bean>
<bean name="source2" class="pojo.Source">
    <property name="fruit" value="橙子"/>
    <property name="sugar" value="少糖"/>
    <property name="size" value="小杯"/>
</bean>

Spring对这种情况提供了2个注解进行解决:

@Primary 注解

定义:代表首要的,当 Spring IoC 检测到有多个相同类型的 Bean 资源的时候,会优先注入使用该注解的类。

问题:该注解只是解决了首要的问题,但是并没有选择性的问题。

@Qualifier 注解

定义:此注解可以让Spring使用name的方式进行Bean的装配以及注入

/* 包名和import */
public class JuiceMaker {
    ......
    @Autowired
    @Qualifier("source1")//指定注入名称为 "source1" 的 Bean 资源
    public void setSource(Source source) {
        this.source = source;
    }
}

2、使用@Bean 装配 Bean

基础用法

定义:@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。

用法:标识这个方法可以产生一个Bean并且交给Spring容器管理,告诉Spring可以在这个方法中拿到一个Bean。

PS:添加的bean的id为方法名

@Configuration
public class AppConfig {

    @Bean//用@Bean注解配置Bean时,bean的ID默认为方法的名称
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}

上面的代码等同于

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

bean的依赖

@bean 也可以依赖其他任意数量的bean,如果TransferService 依赖 AccountRepository,我们可以通过方法参数实现这个依赖。

@Configuration
public class AppConfig {

    @Bean
    public TransferService transferService(AccountRepository accountRepository) {//PS:此方法的入参就是返回值所依赖的对象
        return new TransferServiceImpl(accountRepository);
    }

}

3、Bean的作用域

可以通过 @Scope 注解或者 <bean> 元素中的 scope 属性来设置Bean的作用域

4、Spring 表达式

一个例子简单了解下: 

package pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("elBean")
public class ElBean {
    // 通过 beanName 获取 bean,然后注入role这个对象
    @Value("#{role}")
    private Role role;
    
    // 获取 bean 的属性 id,并注入给id这个变量
    @Value("#{role.id}")
    private Long id;
    
    // 调用 bean 的 getNote 方法,并注入给note这个变量
    @Value("#{role.getNote().toString()}")
    private String note;
    /* getter and setter */
}

小结: 

@Value("#{}") 表示SpEl表达式,通常用来获取bean的属性,或者调用bean的某个方法,或者常量注入

PS:简要的说,就是通过@Value这个注解注入对象或者属性给相应的变量(简单的理解为赋值操作)。

 

参考资料:

posted @ 2019-09-17 18:02  有梦想的肥宅  阅读(374)  评论(0编辑  收藏  举报