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


 
假设我们具有如下配置 , 将firstMovieCatalog定义为主要的MovieCatalog 。
@Configurationpublic class MovieConfiguration {@Bean@Primarypublic MovieCatalog firstMovieCatalog() { ... }@Beanpublic MovieCatalog secondMovieCatalog() { ... }// ...}根据这样的配置 , 下面的MovieRecommender将用firstMovieCatalog进行自动装配 。
public class MovieRecommender {@Autowiredprivate MovieCatalog movieCatalog;// ...}对应的 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" primary="true"></bean><bean class="example.SimpleMovieCatalog"></bean><bean id="movieRecommender" class="example.MovieRecommender"/></beans>3.9.4 微调基于注解且带有限定符的自动装配当有多个实例需要确定一个主要的候选对象时 , @Primary是一种按类型自动装配的有效方式 。当需要在选择过程中进行更多的控制时 , 可以使用 Spring 的@Qualifier注解 。为了给每个选择一个特定的 bean , 你可以将限定符的值与特定的参数联系在一起 , 减少类型匹配集合 。在最简单的情况下 , 这是一个纯描述性值:
public class MovieRecommender {@Autowired@Qualifier("main")private MovieCatalog movieCatalog;// ...}@Qualifier注解也可以指定单个构造函数参数或方法参数:
public class MovieRecommender {private MovieCatalog movieCatalog;private CustomerPreferenceDao customerPreferenceDao;@Autowiredpublic void prepare(@Qualifier("main")MovieCatalog movieCatalog,CustomerPreferenceDao customerPreferenceDao) {this.movieCatalog = movieCatalog;this.customerPreferenceDao = customerPreferenceDao;}// ...}对应的 bean 定义如下 。限定符值为”main”的 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 value=https://www.isolves.com/it/cxkf/rongqi/2022-04-18/"main"/>

<bean class="example.SimpleMovieCatalog">
 
<qualifier value=https://www.isolves.com/it/cxkf/rongqi/2022-04-18/"action"/>
 
</bean>
 
<bean id="movieRecommender" class="example.MovieRecommender"/>
 
</beans>
对于回退匹配 , bean 名字被认为是默认的限定符值 。因此你可以定义一个 id 为main的 bean 来代替内嵌的限定符元素 , 会有同样的匹配结果 。然而 , 尽管你可以使用这个约定根据名字引用特定的 beans , 但是@Autowired从根本上来讲是使用可选的语义限定符来进行类型驱动注入的 。这意味着限定符的值 , 即使回退到 bean 名称 , 总是缩小语义类型匹配的集合;它们没有从语义上将一个引用表达为一个唯一的 bean id 。好的限定符值是”main”或”EMEA”或”persistent” , 表达一个特定组件的性质 , 这个组件是独立于 bean id的 , 即使前面例子中像这个 bean 一样的匿名 bean 会自动生成 id 。
 
正如前面讨论的那样 , 限定符也可以应用到类型结合上 , 例如 , Set<MovieCatalog> 。在这个例子中 , 根据声明的限定符匹配的所有 beans 作为一个集合进行注入 。这意味着限定符不必是唯一的;它们只是构成过滤标准 。例如 , 你可以定义多个具有同样限定符值”action”的MovieCatalog , 所有的这些都将注入到带有注解@Qualifier("action")的Set<MovieCatalog>中 。


推荐阅读