Spring4.0系列5-@Conditional

这篇文章介绍spring 4的@Conditional注解。在Spring的早期版本你可以通过以下方法来处理条件问题:

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

1、Spring Expression Language(SPEL)

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

Java代码  

  1. <bean id="flag">  
  2.    <constructor-arg value="#{systemProperties['system.propery.flag'] ?: false }" />  
  3. </bean>  
  4. <bean id="testBean">  
  5.     <property name="prop" value="#{ flag ? 'yes' : 'no' }"/>  
  6. </bean>  

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

2、使用Profile

Xml代码  

  1. <!-- 如果没有设置profile,default.xml将被加载 -->  
  2. <!-- 必须放置在配置文件的最底下,后面再也没有bean的定义 -->  
  3. <beans profile="default">  
  4.      <import resource="classpath:default.xml" />  
  5. </beans>  
  6. <!-- some other profile -->  
  7. <beans profile="otherProfile">  
  8.     <import resource="classpath:other-profile.xml" />  
  9. </beans>  

 

3、使用@Conditional

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

@Conditional定义

Java代码  

  1. @Retention(RetentionPolicy.RUNTIME)  
  2. @Target(ElementType.TYPE, ElementType.METHOD)  
  3. public @interface Conditional{  
  4. lass <!--?extends Condition-->[] value();  
  5. }  

 

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

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

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

 

condition接口定义如下:

 

Java代码  

  1. public interface Condition{  
  2. /** Determine if the condition matches. 
  3. * @param context the condition context 
  4. * @param metadata meta-data of the {@link AnnotationMetadata class} or 
  5. * {@link Method method} being checked. 
  6. * @return {@code true} if the condition matches and the component can be registered 
  7. * or {@code false} to veto registration. 
  8. */  
  9. boolean matches(ConditionContext context, AnnotatedTypeMedata metadata);  
  10. }  

 

下面看一个例子:

Java代码  

  1. import org.springframework.context.annotation.Condition;  
  2. import org.springframework.context.annotation.ConditionContext;  
  3. import org.springframework.core.type.AnnotatedTypeMetadata;  
  4.    
  5. public class LinuxCondition implements Condition{  
  6.    
  7.   @Override  
  8.   public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
  9.     return context.getEnvironment().getProperty("os.name").contains("Linux");  }  
  10. }  

 

Java代码  

  1. import org.springframework.context.annotation.Condition;   
  2. import org.springframework.context.annotation.ConditionContext;   
  3. import org.springframework.core.type.AnnotatedTypeMetadata;   
  4.    
  5. public class WindowsCondition implements Condition{  
  6.    
  7.   @Override   
  8.   public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
  9.     return context.getEnvironment().getProperty("os.name").contains("Windows");  
  10.   }  
  11. }  

 

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

 

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

Java代码  

  1. import org.springframework.context.annotation.Bean;  
  2. import org.springframework.context.annotation.Conditional;  
  3. import org.springframework.context.annotation.Configuration;  
  4.    
  5. @Configuration  
  6. public class MyConfiguration {  
  7.    
  8.   @Bean(name="emailerService")  
  9.   @Conditional(WindowsCondition.class)  
  10.   public EmailService windowsEmailerService(){  
  11.       return new WindowsEmailService();  
  12.   }  
  13.    
  14.   @Bean(name="emailerService")  
  15.   @Conditional(LinuxCondition.class)  
  16.   public EmailService linuxEmailerService(){  
  17.     return new LinuxEmailService();  
  18.   }  
  19. }  

 

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

时间: 2024-10-26 10:51:18

Spring4.0系列5-@Conditional的相关文章

Spring4.0系列6-Generic Qualifier(泛型限定)

在Spring4.0里,泛型是可以用来决定哪一个bean需要依赖注入的(无论xml配置还是注解配置). 用一个简单的例子解释.假设你有一个使用了泛型的DAO.   Java代码   public class Dao<T> {     ...   }    现在创建两个实现类的bean: Java代码   import org.springframework.context.annotation.Bean;   import org.springframework.context.annotat

Spring4.0系列4-Meta Annotation(元注解)

spring框架自2.0开始添加注解的支持,之后的每个版本都增加了更多的注解支持.注解为依赖注入,AOP(如事务)提供了更强大和简便的方式.这也导致你要是用一个相同的注解到许多不同的类中去.这篇文章介绍meta annotation来解决这个问题. Meta Annotation(元注解)定义 Spring4.0的许多注解都可以用作meta annotation(元注解).元注解是一种使用在别的注解上的注解.这意味着我们可以使用Spring的注解组合成一个我们自己的注解. 创建组合注解 自定义注

Spring4.0系列7-Ordering Autowired Collections

spring 4.0的一个小特性是在自动注入的时候使用@Order.Spring 2.5中,我们将bean注入List,如下代码: Java代码   import org.springframework.stereotype.Component;   @Component   public class Employee implements Person {   }     Java代码   import org.springframework.stereotype.Component;   

Spring4.0系列8-Groovy DSL

4.0的一个重要特征就是完全支持Groovy,Groovy是spring主导的一门基于JVM的脚本语言(动态语言).在spring 2.x,脚本语言通过 Java scripting engine在Spring中得到支持.而在4.0中,Groovy的变得更重要,Groovy可以替换xml和注解用来作为bean配置. 要使用Groovy,首先用maven下载Groovy的包,pom.xml文件中添加: Xml代码   <dependency>    <groupId>org.code

Spring4.0系列9-websocket简单应用

spring 4.0的一个最大更新是增加了websocket的支持.websocket提供了一个在web应用中的高效.双向的通讯,需要考虑到客户端(浏览器)和服务器之间的高频和低延时消息交换.一般的应用场景有:在线交易.游戏.协作.数据可视化等.   使用websocket需要考虑的浏览器的支持(IE<10不支持),目前主流的浏览器都能很好的支持websocket. websocket协议中有一些子协议,可以从更高的层次实现编程模型,就像我们使用HTTP而不是TCP一样.这些子协议有STOMP,

Spring4.0系列3-@RestController

4.0重要的一个新的改进是@RestController注解,它继承自@Controller注解.4.0之前的版本,spring MVC的组件都使用@Controller来标识当前类是一个控制器servlet.   使用这个特性,我们可以开发REST服务的时候不需要使用@Controller而专门的@RestController.     当你实现一个RESTful web services的时候,response将一直通过response body发送.为了简化开发,Spring 4.0提供了

[CXF REST标准实战系列] 二、Spring4.0 整合 CXF3.0,实现测试接口

Reprint it anywhere u want. 文章Points: 1.介绍RESTful架构风格 2.Spring配置CXF 3.三层初设计,实现WebService接口层 4.撰写HTTPClient 客户端,并实现简单调用     介绍RESTful架构风格     REST是REST之父Roy Thomas创造的,当时提出来了REST的6个特点:客户端-服务器的.无状态的.可缓存的.统一接口.分层系统和按需编码.其具有跨语言和跨平台的优势.     REST是一种架构风格.其描述

ActionScript 3.0系列教程(4):爽快使用XML

xml|教程 ActionScript 3.0系列教程(3):Document Class特色为我们带来了什么? ActionScript 3.0系列教程(4):爽快使用XML 为什么放弃AS2.0选择AS3.0?如果只允许我说三个理由.那么AS3.0对XML的近乎完美的支持绝对是其中一个. 简单说说AS3.0中对于XML支持的不同吧: .AS2.0对XML的支持勉勉强强,将就着可以用.而AS3.0中对XML的支持是全方位的,极其强大和灵活的. AS2.0对XML的支持不是内建的(build-i

Flash ActionScript 3.0系列教程

教程 作者的blog: www.kingda.org ActionScript 3.0系列教程(1):与Flash9先来一次亲密接触! Flash Professional 9 ActionScript 3.0 Preview 版本今天发布了,意味着从此我们从此不仅仅只能使用Flex 2来使用AS3.0,更可以使用我们一直很熟悉的Flash IDE来进行AS3.0开发了. 与Flex 2不同,Flash 9 alpha(即上面的Flash Professional 9 ActionScript