美文网首页
SpringFramework Core(七)

SpringFramework Core(七)

作者: 程序员文集 | 来源:发表于2020-01-01 19:30 被阅读0次

@Primary

由于按类型自动装配可能会导致多个候选对象,因此通常有必要更好地控制选择过程。一种实现此目的的方法是使用Spring的 @Primary注释。

@Primary指示当多个bean是要自动装配到单值依赖项的候选对象时,应给予特定bean优先权。如果候选对象中仅存在一个主bean,则它将成为自动装配的值。

考虑以下定义firstMovieCatalog为主要配置的配置MovieCatalog:

@Configuration
public class MovieConfiguration {

    @Bean
    @Primary
    public MovieCatalog firstMovieCatalog() { ... }

    @Bean
    public MovieCatalog secondMovieCatalog() { ... }

    // ...
}

使用前面的配置,以下内容MovieRecommender将自动连接到 firstMovieCatalog:

public class MovieRecommender {

    @Autowired
    private MovieCatalog movieCatalog;

    // ...
}

限定符 @Qualifier

当您需要对选择过程进行更多控制时,可以使用Spring的@Qualifier注释。您可以将限定符值与特定的参数相关联,从而缩小类型匹配的范围,以便为每个参数选择特定的bean。在最简单的情况下,这可以是简单的描述性值,如以下示例所示:

public class MovieRecommender {

    @Autowired
    @Qualifier("main")
    private MovieCatalog movieCatalog;

    // ...
}

您还可以@Qualifier在各个构造函数参数或方法参数上指定注释,如以下示例所示:

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(@Qualifier("main") MovieCatalog movieCatalog,
            CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

以下示例显示了相应的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/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean class="example.SimpleMovieCatalog">
        <qualifier value="main"/> 

        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean class="example.SimpleMovieCatalog">
        <qualifier value="action"/> 

        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean id="movieRecommender" class="example.MovieRecommender"/>

</beans>

对于后备匹配,bean名称被认为是默认的限定符值。因此,可以使用idof main而不是嵌套的限定符元素来定义bean ,从而得到相同的匹配结果。但是,尽管您可以使用此约定按名称引用特定的bean,但从@Autowired根本上讲,它是带有可选语义限定符的类型驱动的注入。这意味着,即使带有Bean名称后退的限定符值,在类型匹配集中也始终具有狭窄的语义。它们没有在语义上表示对唯一bean的引用id。好的限定符值是main 或EMEA或persistent,表示独立于Bean的特定组件的特征id,如果是匿名bean定义(例如前面的示例中的定义),则可以自动生成。

限定词也适用于类型化的集合,如前所述(例如,) Set<MovieCatalog>。在这种情况下,根据声明的限定符,将所有匹配的bean作为集合注入。这意味着限定词不必是唯一的。相反,它们构成了过滤标准。例如,您可以定义MovieCatalog具有相同限定符值“ action”的多个bean,所有这些都将注入到带Set<MovieCatalog>注释的中@Qualifier("action")。

在类型匹配的候选对象中,让限定符值针对目标Bean名称进行选择,不需要@Qualifier在注入点处进行注释。如果没有其他解析度指示符(例如限定词或主标记),则对于非唯一依赖性情况,Spring将注入点名称(即字段名称或参数名称)与目标Bean名称进行匹配,然后选择同名候选人(如果有)。

您可以创建自己的自定义限定符注释。为此,请定义一个注释并@Qualifier在您的定义中提供该注释,如以下示例所示:

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

    String value();
}

然后,您可以在自动连接的字段和参数上提供自定义限定符,如以下示例所示:

public class MovieRecommender {

    @Autowired
    @Genre("Action")
    private MovieCatalog actionCatalog;

    private MovieCatalog comedyCatalog;

    @Autowired
    public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) {
        this.comedyCatalog = comedyCatalog;
    }

    // ...
}

接下来,您可以提供有关候选bean定义的信息。您可以将<qualifier/>标签添加为 标签的子元素,<bean/>然后指定type和 value以匹配您的自定义限定符注释。该类型与注释的标准类名匹配。另外,为方便起见,如果不存在名称冲突的风险,则可以使用简短的类名。

<?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/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean class="example.SimpleMovieCatalog">
        <qualifier type="Genre" value="Action"/>
        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean class="example.SimpleMovieCatalog">
        <qualifier type="example.Genre" value="Comedy"/>
        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean id="movieRecommender" class="example.MovieRecommender"/>

</beans>

相关文章

网友评论

      本文标题:SpringFramework Core(七)

      本文链接:https://www.haomeiwen.com/subject/xdxuoctx.html