Spring的容器配置可以有两种方式,一种基于XML文件, 一种基于注解。注解注入在XML注入之前执行。因此,当两个同时使用时,XML配置会覆盖注解注入的属性。

本文会主要介绍 @Required,@Autowired, @PostConstruct, @PreDestroy 和 @Resource 这几个注解。

这几个注解都是由 context:annotation-config/ 来引入的。本质上引入这个配置会隐式的注册AutoWiredAnnotationBeanPostProcessor(提供@Autowired),CommonAnnotationBeanPostProcessor(提供@PostConstruct, @PreDestroy, @Resource),RequiredAnnotationBeanPostProcessor(提供 @Required),从而提供各个注解的功能。

下面我们会分别介绍各个注解的功能。

@Required

@Required 一般用在方法上面,表示该方法的参数必须能通过配置或者自动装载来填充。通常如果某个属性是必须的,我们会使用这个注解。

不过从Spring Framework 5.1开始,@Required注解正式被弃用,取而代之的是使用构造函数注入用于所需的属性,或使用InitializingBean.afterPropertiesSet()的自定义实现以及bean属性setter方法。

示例代码如下:

public class RequiredBean {

    private BeanA  beanA;

    @Required
public void setBeanA(BeanA beanA){
this.beanA=beanA; }
}

@Autowired

@Autowired 就是自动注入所需要的字段,参数等。JSR 330的@Inject注解可以代替spring的@Autowired注解。

你可以将@Autowired注解到构造器中,如下所示:

public class AutowiredBean {

    private BeanA beanA;

    @Autowired
public AutowiredBean(BeanA beanA){
this.beanA=beanA;
}
}

从SpringFramework4.3开始,如果目标bean只定义了一个构造函数,那么就不再需要在此类构造函数上使用@Autowired注解。但是,如果有多个构造函数可用,则必须至少对其中一个进行注解,以告诉容器使用哪一个。

@Autowired也可以注解到传统的setter方法,如下例子所示:

public class AutowiredBean {

    private BeanB beanB;

    @Autowired
public void setBeanB(BeanB beanB){
this.beanB=beanB;
}
}

也可以把注解应用到任何名字和多个参数,如下所示:

    @Autowired
public void configAB(BeanA beanA , BeanB beanB){
this.beanA=beanA;
this.beanB=beanB; }

@Autowired也可以用在字段上,如下所示:

    @Autowired
private BeanC beanC;

还可以通过将注解添加到需要该类型数组的字段或方法,那么可以从ApplicationContext中获取到该特定类型的所有bean,如下例所示:

    @Autowired
private BeanC[] beanCList;

如果希望数组或列表中的项按特定顺序排序,目标bean可以实现org.springframework.core.Ordered接口,或者可以使用@Order或标准的@Priority注解。

否则,它们的顺序遵循容器中相应目标bean定义的注册顺序。

Map实例也可以被注入,只要key是String类型。Map value包括了所有的类型匹配的Bean,keys是该bean的名字。如下所示:

    @Autowired
public void configMapA(Map<String,BeanA> mapA){
this.mapA=mapA;
}

@Autowired有个required属性,如果要注入的bean有可能不存在,则可以如下所示:

    @Autowired(required = false)
public void setBeanC(BeanC beanC){
}

建议使用@Autowired的’required’属性而不是使用setter方法上的@Required注解。“required”属性表示自动装载需要该属性, 如果无法自动装载,则忽略该属性。而对于@Required来说,如果未定义任何值,则会报异常。

也可以通过Java 8的java.util.Optional表示特定依赖项的非必需性质,如下示例显示:

    @Autowired
public void setMovieFinder(Optional<BeanC> BeanC) {
}

在Spring Framework 5.0中,你也可以使用@Nullable注解:

    @Autowired
public void setMovieFinderC(@Nullable BeanC beanC) {
}

Spring可以使用@Autowired来自动解析一些默认存在的bean如:BeanFactory、ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher和MessageSource。这些接口及其扩展接口(如ConfigurableApplicationContext或ResourcePatternResolver)。

如下所示,自动注入ApplicationContext:

    @Autowired
private ApplicationContext context;

注意: @Autowired, @Inject, @Value, 和 @Resource 注解是在Spring的BeanPostProcessor中处理的,这意味着你不能将这些注解用在你自己的BeanPostProcessor,BeanFactoryPostProcessor类型。

@primary

当按类型注入的时候,可能会有多个候选项,则可以通过@Primary注解表示优先的对象。如下所示:

@Configuration
public class ConfigBean { @Bean
@Primary
public BeanA firstBeanA() { return new BeanA(); } @Bean
public BeanA secondBeanA() { return new BeanA();} }

@Qualifier

@Primary是一种在多个实例中按类型使用自动装载的有效方法,但是如果你希望对注入的Bean进行更细粒度的控制时候,可以使用@Qualifier。如下所示:

    @Bean
@Qualifier("main")
public BeanC beanC() { return new BeanC();}
    @Autowired
@Qualifier("main")
private BeanA beanA; @Autowired
public void setBeanA(@Qualifier("main") BeanA beanA){ }

限定符的值并不是唯一的,它只是一个过滤标准。

@Autowired一般用来通过类型匹配,@Resource则是通过名称匹配。

也可以创建自定义注解:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre { String value();
}

泛型

除了@Qualifier注解外,还可以使用Java泛型类型作为隐式的限定形式。例如,假设您具有以下配置:

public class StringStore implements Store<String> {
} public class IntegerStore implements Store<Integer> {
}
    @Bean
public StringStore stringStore() {
return new StringStore();
} @Bean
public IntegerStore integerStore() {
return new IntegerStore();
}
public class GenericBean {

    @Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean @Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean // Inject all Store beans as long as they have an <Integer> generic
// Store<String> beans will not appear in this list
@Autowired
private List<Store<Integer>> s; }

@Resource

@Resource用在字段或者Setter方法上,默认情况下@Resource通过名字来注入。

public class ResourceBean {

    @Resource(name = "beanA")
private BeanA BeanA;
}

如果未显式指定名称,则从字段名或setter方法派生默认名称.

在@Resource用法中,如果没有指定显式名称,并且类似于@Autowired,@Resource会找到一个主类型匹配,而不是指定的bean,并解析已知的可解析依赖项:BeanFactory、ApplicationContext、ResourceLoader、ApplicationEventPublisher,和MessageSource接口。

@PostConstruct和@PreDestroy

这两个注解主要用做生命周期回调。如下所示:

public class ConstructBean   {

    @PostConstruct
public void populateMovieCache() {
// populates the movie cache upon initialization...
} @PreDestroy
public void clearMovieCache() {
// clears the movie cache upon destruction...
}
}

与@Resource一样,@PostConstruct和@PreDestroy注解类型是JDK 6到8标准Java库的一部分。然而,整个javax.annotation包与JDK 9中的核心Java模块分离,并最终在JDK 11中被删除。如果需要,javax.annotation-api工件现在需要通过maven central获得,只需像其他库一样添加到应用程序的类路径中即可。

本文的代码可以参考annotation-config

更多教程请参考flydean的博客

Spring5参考指南:基于注解的容器配置的更多相关文章

  1. Spring IOC之基于注解的容器配置

    Spring配置中注解比XML更好吗?基于注解的配置的介绍提出的问题是否这种途径比XML更好.简单来说就是视情况而定. 长一点的答案是每一种方法都有自己的长处也不足,而且这个通常取决于开发者决定哪一种 ...

  2. Spring5参考指南:基于Schema的AOP

    文章目录 基于Schema的AOP 定义Aspect 定义Pointcut 定义Advice advice参数 Advisors 基于Schema的AOP 上篇文章我们讲到了使用注解的形式来使用Spr ...

  3. Spring5参考指南:AspectJ注解

    文章目录 什么是AspectJ注解 启用AOP 定义Aspect 定义Pointcut 切入点指示符(PCD) 切入点组合 Advice 访问JoinPoint Advice参数 Advice参数和泛 ...

  4. Spring5参考指南:IOC容器

    文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...

  5. 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式

    8.4.5 基于注解的“零配置”方式 AspectJ允许使用注解定义切面.切入点和增强处理,而Spring框架则可识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5 一样的 ...

  6. 基于注解的形式配置Bean

    基于注解的方式配置Bean:也就说我们在每个Bean的类名前面注解一下,Spring会自动帮我们扫描Bean放进IOC容器中 I基于注解的方式配置Bean(没有依赖关系的Bean)有两个步骤: 1组件 ...

  7. 10 Spring框架--基于注解的IOC配置

    1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...

  8. spring-第十七篇之spring AOP基于注解的零配置方式

    1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...

  9. 基于注解的bean配置

    基于注解的bean配置,主要是进行applicationContext.xml配置.DAO层类注解.Service层类注解. 1.在applicationContext.xml文件中配置信息如下 &l ...

随机推荐

  1. wifi无线桥接

    考虑到不同路由器配置上或许有细微差别,我此处路由器是水星(牌子)路由器. 首先需要2台路由器,一台已经能够上网,作为主路由器:另一台啥都没有配置,将来用作副路由器,与主路由器桥接. 步骤: 获取主路由 ...

  2. IIS 组成

    HTTP.sys      http.sys 侦听来自网络的 HTTP 请求,将它们传递到 IIS 并返回响应. 它是一种可以从命令行停止和启动的服务.      "NET STOP HTT ...

  3. Shiro 笔记

    功能 认证 授权 加密 session 管理 认证 Subject 是一个与系统交互的实体,可以是人,也可以是其他等 调用 SecurityUtils.getSubject()返回当前Subject, ...

  4. Hadoop安装教程_伪分布式

    文章更新于:2020-04-09 注1:hadoop 的安装及单机配置参见:Hadoop安装教程_单机(含Java.ssh安装配置) 注2:hadoop 的完全分布式配置参见:Hadoop安装教程_分 ...

  5. 虚拟机的vmnet8网卡找不到了

    不知道我设置了什么,在我于Linux中配置网络时发现怎么都不行,检查了一下发现用于NAT的网卡没有了. 我重启了电脑之后发现还是没有. 于是按照网上的办法在虚拟网络编辑器将其重置,如下图. 问题解决. ...

  6. Windows恢复分区管控命令reagentc

    reagentc命令可以实现Windows恢复分区的开关,创建.删除,状态查看. 可以只管确定当前系统恢复分区所在位置,便于删除多余的恢复分区.

  7. linux如何杀死指定进程

    ps aux | grep '进程名称' sudo kill pid

  8. Markdown语法详解-cnblog

    博客的重要性 博客,英文名为Blog,它的正式名称为网络日记. 为什么要写博客? 需要总结和思考.有时候我们一直在赶路,却忘了放慢脚步 提升文笔组织能力 提升学习总结能力 提升逻辑思维能力 帮助他人, ...

  9. 17-jmeter相关插件介绍

    转--https://www.cnblogs.com/imyalost/p/7751981.html

  10. Django 表单处理流程

    Django 的表单处理:视图获取请求,执行所需的任何操作,包括从模型中读取数据,然后生成并返回HTML页面(从模板中),我们传递一个包含要显示的数据的上下文.使事情变得更复杂的是,服务器还需要能够处 ...