Spring5参考指南:基于注解的容器配置
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参考指南:基于注解的容器配置的更多相关文章
- Spring IOC之基于注解的容器配置
Spring配置中注解比XML更好吗?基于注解的配置的介绍提出的问题是否这种途径比XML更好.简单来说就是视情况而定. 长一点的答案是每一种方法都有自己的长处也不足,而且这个通常取决于开发者决定哪一种 ...
- Spring5参考指南:基于Schema的AOP
文章目录 基于Schema的AOP 定义Aspect 定义Pointcut 定义Advice advice参数 Advisors 基于Schema的AOP 上篇文章我们讲到了使用注解的形式来使用Spr ...
- Spring5参考指南:AspectJ注解
文章目录 什么是AspectJ注解 启用AOP 定义Aspect 定义Pointcut 切入点指示符(PCD) 切入点组合 Advice 访问JoinPoint Advice参数 Advice参数和泛 ...
- Spring5参考指南:IOC容器
文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...
- 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式
8.4.5 基于注解的“零配置”方式 AspectJ允许使用注解定义切面.切入点和增强处理,而Spring框架则可识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5 一样的 ...
- 基于注解的形式配置Bean
基于注解的方式配置Bean:也就说我们在每个Bean的类名前面注解一下,Spring会自动帮我们扫描Bean放进IOC容器中 I基于注解的方式配置Bean(没有依赖关系的Bean)有两个步骤: 1组件 ...
- 10 Spring框架--基于注解的IOC配置
1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...
- spring-第十七篇之spring AOP基于注解的零配置方式
1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...
- 基于注解的bean配置
基于注解的bean配置,主要是进行applicationContext.xml配置.DAO层类注解.Service层类注解. 1.在applicationContext.xml文件中配置信息如下 &l ...
随机推荐
- 根据银行卡号 获取银行名称及银行logo
根据银行卡号码获取银行卡归属地信息接口地址: https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8 ...
- 1038 Recover the Smallest Number (30分)(贪心)
Given a collection of number segments, you are supposed to recover the smallest number from them. Fo ...
- 解决MySQL workbench的resultgird不出现的问题
23:01:37 2019-08-08 鸽了好久 终于开始看怎么使用MySQL workbench了 首先就是遇到了result gird不显示的问题 搜了 重启是一种办法(这方法...至少能用) 其 ...
- 摩尔投票算法( Boyer-Moore Voting Algorithm)
一.Majority Element题目介绍:给定一个长度为n的数组的时候,找出其中的主元素,即该元素在数组中出现的次数大于n/2的取整.题目中已经假定所给的数组一定含有元素,且主元素一定存在.一下是 ...
- python中使用163邮箱发送邮件一直报错的问题,谁能解决(已经各种百度完了,没能解决问题)
1.报错如下: 2.代码如下:
- python--装饰器、生成器、迭代器、元类
一.装饰器 def w1(func): def inner(): func() return inner @w1 def f1(): ') 1.只要python解释器执行到装饰器,就会自动进行装饰,而 ...
- java对于目录下的相关文件的单词操作
写入文件的目录.代码通过找目录下的文件,进行相关函数的操作.如果目录下面包含子目录.代码设有调用递归的方法,在寻找子目录下的文件 在进行相关的函数操作.函数主要是按用户输入的个数要求输出文件中出现次数 ...
- MTK Android 设置下添加一级菜单[ZedielPcbTest]
功能描述:Android7.1.2 设置下添加一级菜单[ZedielPcbTest],点击ZedielPcbTest,启动ZedielPcbTest.apk应用. 编译:需要在out目录删除Settt ...
- python 网络编程---粘包
一.什么是粘包?(只有在TCP中有粘包现象,在UDP中永远不会粘包) 黏包不一定会发生. 如果发生 了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了. 所谓的粘包问题:主要是是因为 ...
- TCP协议的安全性分析
有算法就有破解法,因为它们都遵循了一定的数据结构和数学知识.所以网络安全是一个相对的概念,不可能出现绝对的安全!作为当今最流行的网络协议--TCP也是如此.那么TCP的安全问题究竟是哪些因素引起的呢? ...