Spring入门(Bean装配,@Qualifier)

本文介绍Spring框架中@Qualifier注解的使用方法,包括如何缩小自动装配的范围及指定唯一bean实例。探讨了@Qualifier在成员变量、构造器及方法参数中的应用,并展示了自定义Qualifier的过程。

当按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数。
可用于注解集合类型变量。

比如说按类型装配可能有多个bean的时候,在前一篇的例子中提到,可以使用@Autowired去注解List<>、Set<>这样的数组集合,或者是Map<>这样的键值对,然后可以把同一种类型的bean注册到list或者map当中去。那么在这种情况下使用@Qualifier可以缩小注解的范围,或者可以指定唯一的bean。
也就是说按照刚才的例子,BeanInterface和BeanImplOne、BeanImplTwo,如果我们在类中声明了一个BeanInterface类型的成员变量,我们可以指定用One或者Two哪一个实现类。
当然,它可以用于具体的单独的构造器函数或者是方法的参数。看一下例子:

public class MovieRecommender{

    @Autowired
    @Qualifier("main")
    private MovieCatalog movieCatalog;
}

首先用@Autowired注解,当然,如果有多个这种MovieCatalog的时候,我们可以通过@Qualifier来指定使用main也就是bean的id为main的MovieCatalog的实现类或者是子类。
上边这种情况使用在成员变量上,它也可以用在方法参数中:

public class MovieRecommender{

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(@Qualifier("main")MovieCatalog movieCatalog,
            CustomerPreferenceDao customerPreferenceDao){
        this.movieCatalog=movieCatalog;
        this.customerPreferenceDao=customerPreferenceDao;
    }
    //...
}

在这个prepare()方法中,第一个参数MovieCatalog,我们可以指定@Qualifier,那它就是用
MovieCatalog对应bean的id为main的bean的实例。这也是@Qualifier这个注解用的最多的一个场景。

如何在xml文件中来实现这种@Qualifier?

<bean class="example.SimpleMovieCatalog">
    <qualifier value="main"/>
</bean>

这就是在xml配置文件中使用@Qualifier。

如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术上能够通过@Qualifier指定bean的名字,然后再通过@Autowired进行注入),替代方式是使用JSR-250标准中的@Resource注解,它是通过其独特的名称来定义俩识别特定的目标(这是一个与声明的类型是无关的匹配过程)。
因语义差异,集合或Map类型的bean无法通过@Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@Resource注解,可以通过唯一名称引用集合或Map的bean。
@Autowired适用于fields(字段)、constructors(构造器)、multi-argument methods(多参数的方法)这些允许在参数级别使用@Qualifier注解缩小范围的情况。
@Resource适用于成员变量、只有一个参数的setter方法,所以在目标是构造器或一个多参数方法时,最好的方式是使用qualifiers。


可以定义自己的qualifier注解并使用。
比如定义一个自己的Qualifier,有个value的变量,当在某个类中去使用自定义的Qualifier,可以达到一样的效果。那通过什么样的方式呢?
就是定义自己的注解的时候,用@Qualifier来注解我们自定义的注解,那么我们自定义的注解就具有了相应的功能。

@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre{
    String value();
}
public class MovieCatalog{

    @Autowired
    @Genre("Action")
    private MovieCatalog actionCatalog;
    private MovieCatalog comedyCatalog;

    @Autowired
    public void setComedyCatalog(@Genre("Comedy")MovieCatalog comedyCatalog){
        this.comedyCatalog=comedyCatalog;
    }
    //...
}

这也是自定义注解的一种方式,使用了xml配置文件的方式。

<bean class="example.SimpleMovieCatalog">
    <qualifier type="Genre" value="Action"/>
</bean>
<bean class="example.SimpleMovieCatalog">
    <qualifier type="example.Genre" value="Comedy"/>
</bean>

举例

之前讲到的BeanInterface类有两个实现类BeanImplOne和BeanImplTwo,调用类BeanInvoker。
在调用类里加上代码

@Autowired
@Qualifier("beanImplTwo")
private BeanInterface beanInterface;

if (null != beanInterface) {
    System.out.println(beanInterface.getClass().getName());
} else {
    System.out.println("beanInterface is null...");
}

由于BeanInterface有两个实现类,所以可以使用@Qualifier注解同时指定具体使用哪一个实现类。然后在say方法里加上之后的代码。

最终的结果表明@Qualifier注解可以缩小范围,指定到具体的bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值