与xml哪个好, 各有利弊
注释更简洁, XML不需要编译,更擅长链接组件。
有人认为: 注释类不是简单的POJO, 配置分散难控制。
Spring兼容两种,可以混合使用,而且支持无侵入的注释。
Spring 2.0 开始支持 @Required
Spring 2.5 @Autowired @PostConstruct, and @PreDestroy
Spring 3.0 @Inject and @Named
更多可参考 relevant section.
需要加上
<?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>
重点:
<context:annotation-config/> 在 WebApplicationContext for DispatcherServlet, 只会在controllers中检查@Autowired, 不会在services中检查。
1.9.1 @Required
这个注释应用在属性的setter方法上。
必须执行检查。
1.9.1 @Autowired
可以加在构造方法上。
在 Spring 4.3版本, 如果只有一个构造器则不需要加上这个注释;但是如果有多个构造器,则必须指定使用哪一个。
@Autowired也可以使用在其他带有多个参数的方法上。也可以在属性上和构造函数上同时使用
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
}
也可以使用在数组上
public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}
}
等效于以下:
public class MovieRecommender {
private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
}
目标bean这里是 MovieCatalog, 可以继承org.springframework.core.Ordered接口, 使用 @Order 或者@Priority注释设定顺序。否则会根据注册的顺序。
标准的javax.annotation.Priority 注释自从无法在方法上声明后在@Bean层级就无法使用了, 可以通过@Order 结合@Primary 达成。
Map类型的也可以autowired,
public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
}
如果找不到合适的bean的话, autowire会失败, 可以通过设置required = false
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
}
重要:一个类只能有一个构造函数可以标识为required, 但是可以有多个构造函数可以表示为 non-required. 在这种状况下, spring使用参数最多的构造函数。
java8 可以使用java.util.Optional来处理非必须的特性。
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
}
在Spring 5中, 可以使用@Nullable 注释
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
}
eanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher, and MessageSource这些也可以使用@Autowired。
public class MovieRecommender {
@Autowired
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
}
1.9.3 使用@Primary 可以很好调优基于注解的自动装配
@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
}
使用这个配置之后, 以下会自动装配firstMovieCatalog
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
// ...
}
}
<?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>
1.9.4 使用@Qualifier 调优
@Primary可以指定先用哪一个,更多的控制可以使用@Qualifier
public class MovieRecommender {
@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
// ...
}
}
@Qualifier也可以使用在构造函数的参数上
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;
}
// ...
}
}
@Qualifier也可以定制
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
String value();
}
}
1.9.7 @Resource
@Resource - JSR-250
@Resource有name的属性, spring 会将其作为bean的名字
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
}
如果没有指定 name, 则会使用setter 的name。
1.9.8. @PostConstruct and @PreDestroy
- 空白目录
- 0.环境准备
- 0.1基于maven的工程创建
- 1.控制反转容器
- 1.1 Spring控制反转容器和beans介绍
- 1.2 容器概览
- 1.3 Bean概览
- 1.4 依赖
- 1.5 Bean的范围
- 1.6 客制bean的特性
- 1.7 Bean定义的继承
- 1.8 容器扩展点
- 1.9 基于注解的容器配置
- 1.10 类路径扫描及组件管理
- 1.11 使用JSR 330标准的注解
- 1.12 基于Java的容器配置
- 1.12.1 基本概念: @Bean 和 @Configuration
- 1.13 环境抽象化
- 1.14 注册一个LoadTimeWeaver
- 1.15 ApplicationContext的附加功能
- 1.16 BeanFactory
- 2. 资源
- 3. 验证,数据绑定和类型转换
- 4. Spring表达式语言(SpEL)
- 5. Spring面向方面的切面编程
- 6. Spring AOP 接口
- 7. 空安全
- 8. 数据缓冲和编码
- 9. 附录