Spring 4引入了一个称为Conditional的新功能,该功能针对于生成bean的Spring组件,并注视这些bean的生成,实质上,它提供了一种条件生成bean的方法。

考虑一个简单的例子:

我有一个名为“ CustomerService”的服务,该服务有两个实现,例如“ CustomerService1”和“ CustomerService2”。 基于系统属性(例如“ servicedefault”)的存在,我要创建默认的“ CustomerService1”实现,如果不存在,则要创建“ CustomerService2”的实例。

使用基于Java配置的Spring bean定义,我可以这样做:

@Configuration
public static class ContextConfig {@Beanpublic CustomerService customerService() {if (System.getProperty("servicedefault")!=null) {return new CustomerServiceImpl1();}return new CustomerServiceImpl2();}
}

另一种方法是使用Spring 3.1引入的Spring Bean Profiles :

@Bean
@Profile("default")
public CustomerService service1() {return new CustomerServiceImpl1();
}@Bean
@Profile("prod")
public CustomerService service2() {return new CustomerServiceImpl2();
}

但是,此特定实例中的Profiles有点笨拙,因为很难设置用于管理一个bean的实现策略的配置文件,它更适合需要控制一组bean的行为的情况。

Spring 4引入了条件注释,可以用一些可重用的方式来实现此行为。

条件依赖于一组条件类来指定谓词,这种方式是:

class HardCodedSystemPropertyPresentCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return (System.getProperty("servicedefault") != null);}
}class HardCodedSystemPropertyAbsentCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return (System.getProperty("servicedefault") == null);}
}

我需要两个谓词,一个用于指定肯定条件,一个用于指定否定条件,这些谓词现在可以应用于bean定义:

@Bean
@Conditional(HardCodedSystemPropertyPresentCondition.class)
public CustomerService service1() {return new CustomerServiceImpl1();
}@Bean
@Conditional(HardCodedSystemPropertyAbsentCondition.class)
public CustomerService service2() {return new CustomerServiceImpl2();
}

但是,请注意,条件代码中有一个硬编码的系统属性名称“ servicedefault”,可以使用元注释进一步清除它。 可以通过以下方式定义新的元注释:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(OnSystemPropertyCondition.class)
public @interface ConditionalOnSystemProperty {public String value();public boolean exists() default true;
}

此元注释ConditionalOnSystemProperty接受两个用户指定的属性-系统属性名称的“值”和“存在”以检查该属性是否存在或检查该属性不存在。 该元注释使用@Conditional注释进行标记,该注释指向Condition类以触发使用此新的meta注释进行注释的bean,Condition类如下:

public class OnSystemPropertyCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName());Boolean systemPropertyExistsCheck = (Boolean)attributes.get("exists");String systemProperty = (String)attributes.get("value");if ((systemPropertyExistsCheck && (System.getProperty(systemProperty) != null)) ||(!systemPropertyExistsCheck && (System.getProperty(systemProperty) == null))) {return true;}return false;}
}

这里的逻辑是使用元注释来掌握@Bean实例上定义的属性,并基于附加的“ exists”属性触发检查系统属性是否存在。 现在,可以在@Bean实例上定义此可重用的元注释,以通过以下方式有条件地创建bean:

@Configuration
public static class ContextConfig {@Bean@ConditionalOnSystemProperty("servicedefault")public CustomerService service1() {return new CustomerServiceImpl1();}@Bean@ConditionalOnSystemProperty(value="servicedefault", exists=false)public CustomerService service2() {return new CustomerServiceImpl2();}
}

包起来

这里的示例很简单,可能不是很现实,仅用于演示条件功能。 在Spring 4中,一个更好的例子是使用条件修改我之前提到的基于Spring 3.1的Profiles本身的行为的方式,
现在, Profiles在内部基于基于条件的元注释:

@Conditional(ProfileCondition.class)
public @interface Profile {String[] value();
}
参考: Spring4有条件,来自我们的JCG合作伙伴 Biju Kunjummen,在all和其他博客上。

翻译自: https://www.javacodegeeks.com/2013/10/spring-4-conditional.html

Spring4有条件相关推荐

  1. spring条件注解有哪些_Spring4有条件

    spring条件注解有哪些 Spring 4引入了一个称为Conditional的新功能,该功能针对于生成bean的Spring组件,并注视这些bean的生成,实质上,它提供了一种条件生成bean的方 ...

  2. 形象生动的SpringBoot和SpringMVC的区别

    spring boot只是一个配置工具,整合工具,辅助工具. springmvc是框架,项目中实际运行的代码 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等 ...

  3. Spring Boot 到底是怎么做到自动配置的?

    作者:祖大帅 juejin.im/post/5b679fbc5188251aad213110 SpringBoot的故事从一个面试题开始 Spring Boot.Spring MVC 和 Spring ...

  4. 帮你理清 SpringBoot 与 SpringMVC 的关系

    spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc.spring mvc 只是spring 处理web层请求的一个模块. ...

  5. Spring SpringMVC SpringBoot SpringCloud概念、关系及区别

    一.正面解读: Spring主要是基于IOC反转Beans管理Bean类,主要依存于SSH框架(Struts+Spring+Hibernate)这个MVC框架,所以定位很明确,Struts主要负责表示 ...

  6. 框架:spring、springmvc、springboot

    先来说说spring.springmvc.springboot的关系. spring boot只是一个配置工具,整合工具,辅助工具. springmvc是框架,项目中实际运行的代码 Spring 框架 ...

  7. springboot aop使用_Spring Boot 的自动配置,是如何实现的?

    点击上方"IT牧场",选择"设为星标"技术干货每日送达! 作者 | 祖大帅 链接 | juejin.im/post/5b679fbc5188251aad2131 ...

  8. SpringMVC+JWT+Swagger UI+RestFul

    前言: 其实很早就想写这篇文章了,因为我觉得这会对很多新手有指引作用,当初自己也是瞎子过河的摸索着过来的.目前后台开发比较流行的MVC框架中使用Spring MVC还是比较多的,当然还有Spring ...

  9. SpringBoot是什么?可以做什么?

    SpringBoot入门介绍 什么是springboot Spring Boot 是所有基于 Spring 开发的项目的起点.Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应 ...

最新文章

  1. HDU 4635 Strongly connected(缩点、最多可加边数使得仍然非强连通)
  2. CAN 总线 之六 BOSCH CAN 比特位填充(编码规则)、归零编码(RZ)和不归零编码(NRZ)
  3. IntelliJ中的远程调试Wildfly应用程序
  4. 【LeetCode笔记】76. 最小覆盖子串(字符串、滑动窗口)
  5. R语言快速学习第一部分(有其他语言基础)
  6. linux查看接口的命令,linux shell命令查看接口索引--ip link show
  7. linux从服务器获取共享列表失败,linux – 如何获取连接到本地网络中NFS服务器的客户端列表?...
  8. 企业级NFS网络文件共享服务
  9. UEFI 文件类型.efi
  10. vcpkg安装boost的一些问题,
  11. Git详细教程(三):window系统下,使用Git Gui管理项目
  12. linux中怎样隐藏文件,Linux下如何隐藏文件
  13. 电信无限流量卡为什么无服务器,为什么移动、联通、电信4G无限流量卡都必须限速,怎么回事?...
  14. RobotFramework set global/suite/test variable
  15. 图像处理算法之模糊检测
  16. Quantifying causality in data science with quasi-experiments
  17. scrapy多个url爬虫
  18. 基于Matlab的交通限速标志的识别系统 数字图像处理大作业
  19. [转帖]兆芯发布国产X86处理器KX-6000和KH-30000,性能提升达50%,附详情介绍
  20. 2019年java_Java回顾#4 – 2019年令人失望

热门文章

  1. 如何设置电脑自动锁屏_这个手机锁屏密码竟可以根据时间而变化!密码每分钟都会发生改变...
  2. 转:认识cpu、核与线程
  3. tomcat(20)基于JMX的管理
  4. 进程间通信(IPC)+进程加锁解锁
  5. RabbitMQ消息
  6. 使用静态代理模式实现公用的报表导出功能
  7. java 示例_功能Java示例 第5部分–将I / O移到外部
  8. spring boot缓存_Spring Boot和缓存抽象
  9. 使用Spring Data R2DBC进行异步RDBMS访问
  10. jax-rs jax-ws_使用JAX-RS的HTTP缓存