5 使用泛型作为自动装配限定符
除了@Qualifier
注解外,也可以使用Java的泛型类型作为限定符的一种暗示方式。例如,假设你有如下配置:
@Configuration public class MyConfiguration { @Bean public StringStore stringStore() { return new StringStore(); } @Bean public IntegerStore integerStore() { return new IntegerStore(); } }
假设上面的beans实现了一个泛型接口,例如,Store
和Store
,你可以@Autowire
Store
接口,泛型将作为限定符使用:
@Autowired private Store<String> s1; // <String> qualifier, injects the stringStore bean @Autowired private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean
当自动装配Lists
,Maps
和Arrays
时,也会应用泛型限定符:
// 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并解析已知的可解析依赖:BeanFactory,ApplicationContext,ResourceLoader,ApplicationEventPublisher和MessageSource接口。
因此在下面的例子中,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... } }