基于注解的配置

其实后面咱们曾经在基于注解配置了,这是因为集体比拟喜爱基于注解配置。

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:

ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessorEventListenerMethodProcessor

比方@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