博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring4.0之五:@Conditional在满足特定条件下,才会实例化对象
阅读量:5914 次
发布时间:2019-06-19

本文共 4459 字,大约阅读时间需要 14 分钟。

这篇文章介绍Spring 4的@Conditional注解。

一、在Spring的早期版本你可以通过以下方法来处理条件问题

  • 3.1之前的版本,使用Spring Expression Language(SPEL)。
  • 3.1版本有个新特性叫profile,用来解决条件问题。

1.1、Spring Expression Language(SPEL)

SPEL有一个三元运算符(if-then-else)可以在配置文件中当作条件语句,如下:

 testBean的prop动态依赖于flag的值。

1.2、使用Profile

二、使用@Conditional

官方文档定义:“Indicates that a component is only eligible for registration when all specified conditions match”,意思是只有满足一些列条件之后创建一个bean

除了自己自定义Condition之外,Spring还提供了很多Condition给我们用

@ConditionalOnClass : classpath中存在该类时起效 @ConditionalOnMissingClass : classpath中不存在该类时起效 @ConditionalOnBean : DI容器中存在该类型Bean时起效 @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效 @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效 @ConditionalOnExpression : SpEL表达式结果为true时 @ConditionalOnProperty : 参数设置或者值一致时起效 @ConditionalOnResource : 指定的文件存在时起效 @ConditionalOnJndi : 指定的JNDI存在时起效 @ConditionalOnJava : 指定的Java版本存在时起效 @ConditionalOnWebApplication : Web应用环境下起效 @ConditionalOnNotWebApplication : 非Web应用环境下起效

@Conditional定义

@Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.TYPE, ElementType.METHOD)  public @interface Conditional{      Class
[] value();}

@Conditional注解主要用在以下位置:

  • 类级别可以放在注标识有@Component(包含@Configuration)的类上
  • 作为一个meta-annotation,组成自定义注解
  • 方法级别可以放在标识由@Bean的方法上

如果一个@Configuration的类标记了@Conditional,所有标识了@Bean的方法和@Import注解导入的相关类将遵从这些条件。

condition接口定义如下:

public interface Condition {    /**     * Determine if the condition matches.     * @param context the condition context     * @param metadata metadata of the {
@link org.springframework.core.type.AnnotationMetadata class} * or {
@link org.springframework.core.type.MethodMetadata method} being checked. * @return {
@code true} if the condition matches and the component can be registered * or {
@code false} to veto registration. */ boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}

下面看一个例子:

package com.dxz.demo.condition;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.type.AnnotatedTypeMetadata;public class LinuxCondition implements Condition {    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        return context.getEnvironment().getProperty("os.name").contains("Linux");    }}package com.dxz.demo.condition;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.type.AnnotatedTypeMetadata;public class WindowsCondition implements Condition {    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        return context.getEnvironment().getProperty("os.name").contains("Windows");    }}

我们有两个类LinuxCondition 和WindowsCondition 。两个类都实现了Condtin接口,重载的方法返回一个基于操作系统类型的布尔值。

下面我们定义两个bean,一个符合条件另外一个不符合条件:

package com.dxz.demo.condition;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Conditional;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfiguration {    @Bean(name = "emailerService")    @Conditional(WindowsCondition.class)    public EmailService windowsEmailerService() {        return new WindowsEmailService();    }    @Bean(name = "emailerService")    @Conditional(LinuxCondition.class)    public EmailService linuxEmailerService() {        return new LinuxEmailService();    }}

 当符合某一个条件的时候,这里的@Bean才会被初始化。 

测试相关其它类:

package com.dxz.demo.condition;public interface EmailService {    public void sendEmail();}package com.dxz.demo.condition;public class WindowsEmailService implements EmailService {    public void sendEmail() {        System.out.println("send windows email");    }}package com.dxz.demo.condition;public class LinuxEmailService implements EmailService {    public void sendEmail() {        System.out.println("send linux email");    }}package com.dxz.demo.condition;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Service;@Servicepublic class ConditionClient {    @Autowired    private EmailService emailService;    @Scheduled(initialDelay = 3000, fixedDelay = 10000)    public void test() {        emailService.sendEmail();    }}

结果:

 

转载地址:http://dogpx.baihongyu.com/

你可能感兴趣的文章
【汇编】C++递归调用实现
查看>>
maven 项目,通过maven编译 解决出现JSP NullPointerException
查看>>
log4j2之简化封装,告别静态成员变量
查看>>
Notadd 应用配置数据导入导出设计
查看>>
插件学习:metisMenu.min.js
查看>>
GitHub 开源的 MySQL 在线更改 Schema 工具
查看>>
(转) Twisted :第十六部分 Twisted 进程守护
查看>>
python3 使用threading模块进行多线程编码实现
查看>>
Java String和Date的转换
查看>>
MySQL 每秒插入10万行数据的方法
查看>>
JavaScript继承(四)——原型式继承
查看>>
Greenplum 数据的装载与卸载
查看>>
Objective C运行时(runtime)技术总结,好强大的runtime
查看>>
微信小游戏开发,需要用到哪些接口?
查看>>
hibernate一级缓存和二级缓存的区别
查看>>
技术公众号
查看>>
[转] Linux下使用PyInstaller打包Python程序
查看>>
ubuntu 13.10下设立使用双拼/谷歌拼音等输入法(安装fcitx)
查看>>
GROUP BY GROUPING SETS
查看>>
简单笔记
查看>>