spring 框架说明文档学习记录(3.7)

时间:2022-06-30 05:42:07

基于注解的容器配置


注解注入在XML注入之前被执行,两种方式都是后面的配置会覆盖前面的配置。

你可以注册单独的bean定义,也可以含蓄的使用如下xml配置

<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>

<contex:annotation-config/>仅查找当前application context下的bean上的注解,也就是说,如果我们在DispatcherServlet的WebApplication中配置<context:annotation />,它只会查找controllers中@Autowired的bean,而不会查找services。

@Required

@Required注解适用于bean的属性设置方法,如下

public class SimpleMovieLister {
private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
该注解只是简单表示,受影响的bean属性必须在配置时间内填充,通过bean的定义或自动装配。如果受影响的bean属性没有被填充,则会抛出异常。


@Autowired

JSR330的@Inject注解可以替代Spring的@Autowired注解

我们可以如下使用@Autowired注解

public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}

自Spring Framework4.3起,如果只定义一个构造函数,@Autowired构造函数不再必需。如果有多个构造函数,至少有一个需要被注解来让容器知道使用哪个。

@Autowired注解也可以应用于setter方法

public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}

也可以在多参方法上应用@Autowired注解

public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
也可以属性与构造函数上混合使用

public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
通过在一个预期数组的属性或方法上使用@Autowired,可以从ApplicationCOntext获取该类型的所有bean

public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}

同样可以适用于类型集合

public class MovieRecommender {
private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}

可以适用于Map,map的values值包含所有期望的bean,keys包含bean的名称

public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
没有候选bean时,绑定失败,默认所有的autowired是显式required的。

可以通过定义required=false来标识绑定属性为非必需的

public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required=false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
相比较@Required而言,推荐使用@Autowired的required属性,@Required强制要求属性必须被设置,否则抛出异常。

你也可以在一些公认接口上使用@Autowired,BeanFactory, ApplicationContext, Environment, ResourceLoader,
ApplicationEventPublisher, 和MessageSource

public class MovieRecommender {
@Autowired
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
@Primary

因为通过类型绑定的@Autowired,可能会有多个候选,所有通常需要制定选择流程。如下

@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
当使用该配置时,如下程序绑定到firstMovieCatalog的bean

public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
// ...
}

同等bean定义如下

<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="example.SimpleMovieCatalog" primary="true">
<!-- inject any dependencies required by this bean -->
</bean>
<bean class="example.SimpleMovieCatalog">
<!-- inject any dependencies required by this bean -->
</bean>
<bean id="movieRecommender" class="example.MovieRecommender"/>
</beans>