关于Spring注解容器配置的那些事,掌握这几点,不再难!(下)

5 使用泛型作为自动装配限定符

除了@Qualifier注解外,也可以使用Java的泛型类型作为限定符的一种暗示方式。例如,假设你有如下配置:

@Configuration
public class MyConfiguration {

    @Bean
    public StringStore stringStore() {
        return new StringStore();
    }

    @Bean
    public IntegerStore integerStore() {
        return new IntegerStore();
    }

}

假设上面的beans实现了一个泛型接口,例如,StoreStore,你可以@Autowire Store接口,泛型将作为限定符使用:

@Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean

@Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean

当自动装配ListsMapsArrays时,也会应用泛型限定符

// Inject all Store beans as long as they have an <Integer> generic
// Store<String> beans will not appear in this list
@Autowired
private List<Store<Integer>> s;

3.9.6 CustomAutowireConfigurer

CustomAutowireConfigurer是一个能使你注册自己的定制限定符注解类型的BeanFactoryPostProcessor,即使它们不使用Spring的@Qualifier

<bean id="customAutowireConfigurer"
        class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
    <property name="customQualifierTypes">
        <set>
            <value>example.CustomQualifier</value>
        </set>
    </property>
</bean>

AutowireCandidateResolver通过下面的方式决定自动装配的候选目标:

  • 每个bean定义的autowire-candidate
  • 元素可获得的任何default-autowire-candidates模式
  • 存在@Qualifier注解和任何在CustomAutowireConfigurer中注册的定制注解

当多个beans符合条件成为自动装配的候选目标时,”primary” bean的决定如下:如果在候选目标中某个确定的bean中的primary特性被设为true,它将被选为目标bean。

7 @Resource

Spring也支持使用JSR-250 @Resource对字段或bean属性setter方法进行注入。这是在Java EE 5和6中的一种通用模式,例如在JSF 1.2管理的beans或JAX-WS 2.0的端点。Spring对它管理的对象也支持这种模式。


@Resource采用名字属性,默认情况下Spring将名字值作为要注入的bean的名字。换句话说,它遵循by-name语义,下面的例子证实了这一点:

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource(name="myMovieFinder")
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

}

如果没有显式的指定名字,默认名字从字段名或setter方法中取得。在字段情况下,它采用字段名称;在setter方法情况下,它采用bean的属性名。因此下面的例子将名字为movieFinder的bean注入到它的setter方法中:

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

}

注解提供的名字被CommonAnnotationBeanPostProcessor感知的ApplicationContext解析为bean名字。如果你显式地配置了Spring的SimpleJndiBeanFactory,名字会通过JNDI解析。但是建议你依赖默认行为,简单使用Spring的JNDI查找功能保护间接查找级别。


@Resource特有的没有显式名字指定的情况下,类似于@Autowired@Resource会进行主要的匹配类型来代替指定名字的bean并解析已知的可解析依赖:BeanFactoryApplicationContextResourceLoaderApplicationEventPublisherMessageSource接口。


因此在下面的例子中,customerPreferenceDao字段首先查找名字为customerPreferenceDao的bean,然后回退到主要的类型为customerPreferenceDao的类型匹配。”context”字段会注入基于已知的可解析依赖类型ApplicationContext

public class MovieRecommender {

    @Resource
    private CustomerPreferenceDao customerPreferenceDao;

    @Resource
    private ApplicationContext context;

    public MovieRecommender() {
    }

    // ...

}

8 @PostConstruct和@PreDestroy

CommonAnnotationBeanPostProcessor不仅识别@Resource注解,而且识别JSR-250生命周期注解。在Spring 2.5引入了对这些注解的支持,也提供了在初始化回调函数和销毁回调函数中描述的那些注解的一种可替代方式。假设ommonAnnotationBeanPostProcessor在Spring的ApplicationContext中注册,执行这些注解的方法在生命周期的同一点被调用,作为对应的Spring生命周期接口方法或显式声明的回调方法。在下面的例子中,缓存会预先放置接近初始化之前,并在销毁之前清除。

public class CachingMovieLister {

    @PostConstruct
    public void populateMovieCache() {
        // populates the movie cache upon initialization...
    }

    @PreDestroy
    public void clearMovieCache() {
        // clears the movie cache upon destruction...
    }

}
上一篇:Facebook将成全球最强大数据经纪商


下一篇:亚马逊将扩展在加拿大的数据中心业务