<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
<context:annotation-config/> 元素隐式注册了以下后处理器:
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- PersistenceAnnotationBeanPostProcessor
- EventListenerMethodProcessor
一 使用@Autowired进行元素的自动注入
@Autowired 可以注解到构造方法 类的set方法和属性上
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
你也可以通过在需要该类型数组的字段或方法中添加@Autowired注释来指示Spring从ApplicationContext中提供特定类型的所有bean:
public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}
即使是类型化的Map实例也可以自动连接,只要期望的键类型是String。映射值包含预期类型的所有bean,键包含相应的bean名称,如下所示:
public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
默认情况下必须有一个匹配的元素,但是可以通过required = false属性使他即使匹配不到元素也不会报错
二 使用@Primary微调基于注解的自动装配
@Primary表示,当多个bean是自动连接到单值依赖项的候选者时,应该优先考虑特定的bean。如果候选bean中只存在一个主bean,它将成为自动连接的值。
@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
三 使用@Qualifier微调基于注解的自动装配
1 你可以将限定符值与特定的参数关联起来,缩小类型匹配集,以便为每个参数选择特定的bean。在最简单的情况下,这可以是一个简单的描述性值,如下例所示:
public class MovieRecommender {
@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
// ...
}
@Autowired 主要根据类型匹配 然后根据指定的限定符来匹配@qualifier
@Resource 主要通过name来匹配
2 你可以在自动连接的字段和参数上提供自定义限定符
如下面的例子所示:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
String value();
}
public class MovieRecommender {
@Autowired
@Genre("Action")
private MovieCatalog actionCatalog;
private MovieCatalog comedyCatalog;
@Autowired
public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) {
this.comedyCatalog = comedyCatalog;
}
// ...
}
3 使用泛型作为自动装配限定符:除了@Qualifier注释之外,还可以使用Java泛型类型作为隐式的限定形式。
例如,假设您有以下配置:
@Configuration
public class MyConfiguration {
@Bean
public StringStore stringStore() {
return new StringStore();
}
@Bean
public IntegerStore integerStore() {
return new IntegerStore();
}
}
@Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean
假设前面的bean实现了一个泛型接口(即Store<String>和Store<Integer>),您可以@Autowire Store接口,并将泛型用作限定符,如下面的示例所示:
@Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean
四 使用@Resource注入
@Resource接受一个name属性。默认情况下,Spring将该值解释为要注入的bean名称。如果没有显式指定名称,则默认名称将从字段名称或设置器方法派生。如果是字段,则采用字段名。对于setter方法,它采用bean属性名。
在没有指定显式名称的@Resource使用的独占情况下,与@Autowired类似,@Resource查找主要类型匹配而不是特定的命名bean。
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
五 Using @Value
1 @Value 通常用于外部属性注入
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
默认情况下如果@value的取值不存在,会将catalog.name赋值给属性。如果你想严格控制不存在的值,你应该声明一个PropertySourcesPlaceholderConfigurer bean,如下面的例子所示:
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
2 设置默认值
@Value("${catalog.name:defaultCatalog}
3 自定义类型转换器
@Configuration
public class AppConfig {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}
4 SPEL表达式,spring在运行时会自动计算
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
this.catalog = catalog;
}
}
六 Using @PostConstruct and @PreDestroy
public class CachingMovieLister {
@PostConstruct
public void populateMovieCache() {
// populates the movie cache upon initialization...
}
@PreDestroy
public void clearMovieCache() {
// clears the movie cache upon destruction...
}
}