关于 Spring 注解容器配置的那些事,掌握这几点,不再难( 四 )


 

如果你想通过名字表达注解驱动的注入 , 不要主要使用@Autowired , 虽然在技术上能通过@Qualifier值引用一个 bean 名字 。作为可替代产品 , 可以使用 JSR-250 @Resource注解 , 它在语义上被定义为通过组件唯一的名字来识别特定的目标组件 , 声明的类型与匹配过程无关 。@Autowired有不同的语义:通过类型选择候选 beans , 特定的String限定符值被认为只在类型选择的候选目标中 , 例如 , 在那些标记为具有相同限定符标签的 beans 中匹配一个”account”限定符 。
 
对于那些本身定义在集合/映射或数组类型中的 beans 来说 , @Resource是一个很好的解决方案 , 适用于特定的集合或通过唯一名字区分的数组 bean 。也就是说 , 自 Spring 4.3 起 , 集合/映射和数组类型中也可以通过 Spring 的@Autowired类型匹配算法进行匹配 , 只要元素类型信息在@Bean中保留 , 返回类型签名或集合继承体系 。在这种情况下 , 限定符值可以用来在相同类型的集合中选择 , 正如在前一段中概括的那样 。
 
自 Spring 4.3 起 , @Autowired也考虑自引用注入 , 例如 , 引用返回当前注入的 bean 。注意自注入是备用;普通对其它组件的依赖关系总是优先的 。在这个意义上 , 自引用不参与普通的候选目标选择 , 因此尤其是从不是主要的;恰恰相反 , 它们最终总是最低的优先级 。在实践中 , 自引用只是作为最后的手段 , 例如 , 通过 bean 的事务代理调用同一实例的其它方法:在考虑抽出受影响的方法来分隔代理 bean 的场景中 。或者 , 使用@Resource通过它的唯一名字可能得到一个返回当前 bean 的代理 。
 
@Autowired可以应用到字段 , 构造函数和多参数方法上 , 允许通过限定符注解在参数层面上缩减候选目标 。相比之下 , @Resource仅支持字段和 bean 属性的带有单个参数的 setter 方法 。因此 , 如果你的注入目标是一个构造函数或一个多参数的方法 , 坚持使用限定符 。
 
你可以创建自己的定制限定符注解 。简单定义一个注解 , 在你自己的定义中提供@Qualifier注解:
@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Qualifierpublic @interface Genre {String value();}然后你可以在自动装配的字段和参数上提供定制的限定符:
public class MovieRecommender {@Autowired@Genre("Action")private MovieCatalog actionCatalog;private MovieCatalog comedyCatalog;@Autowiredpublic void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) {this.comedyCatalog = comedyCatalog;}// ...}接下来 , 提供候选 bean 定义的信息 。你可以添加<qualifier/>标记作为<bean/>标记的子元素 , 然后指定匹配你的定制限定符注解的类型和值 。类型用来匹配注解的全限定类名称 。或者 , 如果没有名称冲突的风险 , 为了方便 , 你可以使用简写的类名称 。下面的例子证实了这些方法 。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">context:annotation-config/<bean class="example.SimpleMovieCatalog"><qualifier type="Genre" value=https://www.isolves.com/it/cxkf/rongqi/2022-04-18/"Action"/>在 3.10 小节 , “类路径扫描和管理组件”中 , 你将看到一个基于注解的替代方法 , 在 XML 中提供限定符元数据 。特别地 , 看 3.10.8 小节 , “用注解提供限定符元数据” 。
 
在某些情况下 , 使用没有值的注解就是足够的 。当注解为了通用的目的时 , 这是非常有用的 , 可以应用到跨几个不同类型的依赖上 。例如 , 当网络不可用时 , 你可以提供一个要搜索的离线目录 。首先定义一个简单的注解:


推荐阅读