Spring入门(Bean装配,@Qualifier)

来源:互联网 发布:淘客优惠券网站源码 编辑:程序博客网 时间:2024/06/02 02:29

当按类型自动装配可能多个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)@Qualifierpublic @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。

原创粉丝点击