spring之注解的详解
9 Annotation-based Container Configuration
注解比xml更好吗?
视情况而定!spring支持混合使用。spring的注解让代码编程无侵入式。
除了xml启动外,spring还有基于注解的启动方式–依赖于包裹组件字节码配置信息,而不是描述。除了使用xml描述一个一个bean的信息外,还可以在自己代码处用注解来配置。
第8节的介绍中RequiredAnnotationBeanPostProcessor
示例使用了BeanPostProcess属性来介绍对于参数值得检查。
Spring 2.0中要求用 @Required
注解来介绍。在2.5中,使用
@Autowired
即可,包含了@Required
语义和更多特性。
spring.2.5有对jsr-250的支持,3.0有对JSR-330的支持。
@Required
用法示例
表示在 configuration时期,必须通过一个准确的方法名注入到属性里去。这里会严格的检查,从而避免NullPointerException。
spring5.1里required废弃了
@AutoWired属性
JSR-330 @Inject属性可以代替 @AutoWired
单参数方法
多参数方法
filed和method混合
确保置入点是有效的,否则会报"no type match found"在运行时
置入一整个列表的类
等同于
自定义的bean 可以通过实现Spring.springframework.core.Ordered类,或者使用
@Order
或者标准的@Pritority
属性来标记注入顺序–不会影响Spring的初始化顺序。通过@DependsOn
注解来声明依赖,会影响启动顺序
注意标准的javax.annotation.Priority
,@Bean级别是拿不到的。语义上可以通过 @Order和 @Primary来处理一个Single bean。就是说多个name相同的bean时,需要标记一个主要的
map对象的注入
关闭 required属性
一般的当至少有一个满足的元素(对于集合也是)就不会报错。如果允许为空就要标记 non-required
多构造器问题
描述
:如果存在有类包含多个参数构造器被标记了@Autowired,spirng该如何去选择?
回答
:一次性注入多个值,默认使用构造器是最快的,但是一些类有多个filed去注入(数组,集合,map等需要解决空集合的问题)。通用的模式是:所有的依赖都会对应独一无二的 多参数构造器。当只有一个构造器时,不需要声明@Autowired
只有一个构造器时,不管是否有@Autowired,spirng都会使用。且@Autowired的
required
属性都会为true
。
反之 如果required
属性为true
,那么只有一个被标记为@Autowired
。
如果多个non-required
被标记了@Autowired,它们将会作为备选。若果没有一个满足,那么就会使用默认/主要的构造器。
参数级别的标记null
@nullable
对Spring框架本身的依赖
可以注入:BeanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher, and MessageSource
9.4 注解的微调 @Primary
多个可选的注解时,标记主要的。
如下有两个备选的。
等同于xml
9.5 注解的微调 @Qualifier
@Qualifier比@Primary可以限定更小的范围。
单个属性的缩小范围
属性上的
方法上的
等同于
匹配规则
你需要定义bean的id ,如上图为’main’。如果name属性为main
(可以不唯一),可以启动缩小范围的作用
用于集合的缩小范围
Set属性。一堆MovieCatalog示例被name标记为"action",另一堆被标记为"main",可以用@Qualifier(“action”)选中需要的。
@Resource 是JSR-250的注解,和@Autowired有很小区别,原文有描述,这里忽略。
@Autowired适用于字段,构造函数和多参数方法,从而允许在参数级别缩小@Qualifier注释的范围。相反,只有具有单个参数的字段和bean属性设置器方法才支持@Resource。因此,如果注入目标是构造函数或多参数方法,则应坚持使用@Qualifier限定符。
自定义注解
带值value,也可以不带值
等同于
带固定类型的注解
等同于
9.5 使用 普通类型作为标识
其中 StringStore 和IntegerStore继承了Store的接口。
注入时按类型注入
集合的注入
9.6 使用 CustomAutowireConfigurer 注解的定义
CustomAutowireConfigurer是BeanFactoryPostProcessor,即使您没有使用Spring的@Qualifier注释来注释自己的自定义限定符注释类型,也可以使用它来注册。下面的示例演示如何使用CustomAutowireConfigurer:
AutowireCandidateResolver通过以下方式确定自动装配候选:
-
每个bean定义的autowire-candidate值
-
元素上可用的任何默认autowire-candidates模式
-
@Qualifier批注以及在CustomAutowireConfigurer中注册的所有自定义批注的存在
当多个bean符合自动装配候选条件时,“主要”的确定如下:如果候选中恰好有一个bean定义的主要属性设置为true,则将其选中。
9.7 使用@Resource注解
spring 也支持JSR-250 @Resource注解—在filels和bean的属性setter方法上。
默认依赖bean的name
没有name
默认从filedname和setter方法上找。比如setMovieFinder—>movieFinder
使用注解提供的bean name可以使用ApplicationContext的CommonAnnotationBeanPostProcessor。靠JNDI获取,
在@Resource用法的特殊情况下,未指定显式名称,并且类似于@ Autowired,@ Resource查找主类型匹配而不是特定的命名bean,并解析众所周知的可解决依赖项:BeanFactory,ApplicationContext,ResourceLoader,ApplicationEventPublisher和MessageSource接口。
因此,在以下示例中,customerPreferenceDao字段首先查找名为“ customerPreferenceDao”的bean,然后回退到类型为CustomerPreferenceDao的主类型匹配项
9.8 使用 Using @Value
经典使用
EL获取
配置文件
属性文件
Spring提供了一个默认的宽大内嵌值解析器。它将尝试解析属性值,如果无法解析,则将属性名称(例如$ {catalog.name})作为值注入。如果要严格控制不存在的值,则应声明一个PropertySourcesPlaceholderConfigurer bean,如以下示例所示:
使用JavaConfig配置PropertySourcesPlaceholderConfigurer时,@Bean方法必须是静态的
如果无法解析任何${}占位符,则使用上述配置可确保Spring初始化失败。也可以使用setPlaceholderPrefix,setPlaceholderSuffix或setValueSeparator之类的方法来自定义占位符。
Spring Boot默认配置一个PropertySourcesPlaceholderConfigurer bean,它将从application.properties和application.yml文件获取属性。
默认值
ConversionService 会话服务
Spring BeanPostProcessor在后台使用ConversionService处理将@Value中的String值转换为目标类型的过程。如果要为自己的自定义类型提供转换支持,则可以提供自己的ConversionService bean实例,如以下示例所示
EL表达式的动态拼接
一般数据
数据体
9.9 Using @PostConstruct and @PreDestroy
6的callback中有描述,这里是注解的使用
@PostConstruct–在设置完属性之后
@PreDestroy --在销毁动作之前