基于注解的配置
其实后面咱们曾经在基于注解配置了,这是因为集体比拟喜爱基于注解配置。
Spring 官网文档提过一个问题:基于注解配置要好于基于 xml 的配置吗?其实各有千秋,依据集体爱好吧。重要的是 Spring 能够反对基于注解配置,也能够反对基于 xml 配置文件配置,也能够反对两者的混搭。
咱们能够应用 Spring 的基于 BeanPostProcessor 的 @Autowire 注解,Spring 也反对 JSR-250 的 @PostConstruct 和 @PreDestroy 注解,以及基于 JSR-330 (Dependency Injection for Java) 的注解 @Inject 和 @Named。
基于注解的依赖注入的执行要早于基于 xml 配置文件,所以如果同时应用的话,基于 xml 文件的配置要优先于基于注解的:xml 配置会笼罩掉注解配置。
通过以下配置能够实现混合 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
https://www.springframework.org/schema/context/spring-context.xsd" >
<context:annotation-config/>
<context:component-scan base-package="packageName.packageName"/>
</beans>
基于注解的配置的底层失效原理其实是通过 BeanPostProcessor, 配置项 <context:annotation-config/> 在 Spring 容器中隐式的注册了如下 BeanPostProcessor:
ConfigurationClassPostProcessor
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
EventListenerMethodProcessor
比方 @Autoware 注解就是通过 AutowiredAnnotationBeanPostProcessor(postProcessProperties 办法)失效的。
@Autowired 注解
@Autowired 注解能够作用在构造方法、属性、以及一般办法上,咱们在后面的文章中曾经做过阐明。
作用在构造方法和一般办法上,会主动拆卸办法中的参数,作用在属性上则主动拆卸该属性。
@Autowired 注解是通过类型匹配的,所以增加注解的参数类型和注册到 Spring IoC 容器中的 Bean 的类型必须要匹配,如果 Spring IoC 在主动拆卸的过程中找不到匹配的 Bean 执行注入的话,会产生注入失败,抛异样。
Spring 能够反对将同一类型的 Bean 注入到汇合对象中,比方:
public class MovieRecommender {
private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {this.movieCatalogs = movieCatalogs;}
// ...
}
则 Spring IoC 容器中的所有类型为 MovieCatalog 的 Bean 都会注入到 movieCatalogs 中。MovieCatalog 能够通过实现 org.springframework.core.Ordered 接口或者应用 @Order 注解、@Priority 注解实现排序。
也能够将同类型的对象注入到 Map 中:
public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {this.movieCatalogs = movieCatalogs;}
// ...
}
此时 Map 的 key 值为 bean name,value 值为 bean 对象。
默认状况下 @Autowired 注解冀望必须可能注入一个依赖对象到指标对象中,否则,如果没有匹配到、或者匹配到多个对象的话,注入失败,抛异样。
通过 @Autowired 对汇合类型注入也要求必须要有至多一个 bean 存在,不存在的话会抛异样。
能够通过 @Autowired 的属性 required 来扭转这一行为:默认状况下 required = true,咱们能够批改 required = false,则容许匹配不到依赖对象的状况存在,此时不注入任何对象,指标对象的值为 null。
当 @Autowired 作用于构造方法上的时候,required 设置为 true 的状况下,仅容许有一个构造方法设置为 @Autowired。当多个构造方法被设置为 @Autowired(required 必须设置为 false)的时候,Sping IoC 在注入的时候会抉择构造方法参数依赖注入满足水平最好的结构器执行注入。如果一个类有多个结构器、并且都没有设置 @Autowired,则主结构器、或者默认的结构器会被执行;如果一个类只有一个结构器,那么该结构器就肯定会被执行,即便该结构器并没有标注 @Autowired。
java 8 的 java.util.Optional、以及 @Nullable(Spring5.0 当前)同样能够用来标注 @Autowired 为非必须(等同于 required=false):
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {...}
}
最初:
The @Autowired, @Inject, @Value, and @Resource annotations are handled by Spring BeanPostProcessor implementations. This means that you cannot apply these annotations within your own BeanPostProcessor or BeanFactoryPostProcessor types (if any). These types must be ‘wired up’ explicitly by using XML or a Spring @Bean method.
因为 @Autowired, @Inject, @Value, and @Resource 是通过 BeanPostProcessor 实现的,所以如果你本人实现了一个 BeanPostProcessor,那就不能用以上几个注解,用以上几个注解是无奈实现 BeanPostProcessor 性能的(错过了 BeanPostProcessor 的机会)。
上一篇 Spring FrameWork 从入门到 NB -Lazy-initialized Beans