Spring4.0系列5-@Conditional
Spring4.0系列4-Meta Annotation(元注解)
Spring4.0系列6-Generic Qualifier(泛型限定)
Spring4.0系列7-Ordering Autowired Collections
更多正在编写中。。。
这篇文章介绍Spring 4的@Conditional注解。在Spring的早期版本你可以通过以下方法来处理条件问题:
- 3.1之前的版本,使用Spring Expression Language(SPEL)。
- 3.1版本有个新特性叫profile,用来解决条件问题。
1、Spring Expression Language(SPEL)
SPEL有一个三元运算符(if-then-else)可以在配置文件中当作条件语句,如下:
<bean id="flag"> <constructor-arg value="#{systemProperties['system.propery.flag'] ?: false }" /> </bean> <bean id="testBean"> <property name="prop" value="#{ flag ? 'yes' : 'no' }"/> </bean>
testBean的prop动态依赖于flag的值。
2、使用Profile
<!-- 如果没有设置profile,default.xml将被加载 --> <!-- 必须放置在配置文件的最底下,后面再也没有bean的定义 --> <beans profile="default"> <import resource="classpath:default.xml" /> </beans> <!-- some other profile --> <beans profile="otherProfile"> <import resource="classpath:other-profile.xml" /> </beans>
3、使用@Conditional
官方文档定义:“Indicates that a component is only eligible for registration when all specified conditions match”,意思是只有满足一些列条件之后创建一个bean。
@Conditional定义
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE, ElementType.METHOD) public @interface Conditional{ Class <!--?extends Condition-->[] 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 meta-data of the {@link AnnotationMetadata class} or * {@link Method 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, AnnotatedTypeMedata metadata); }
下面看一个例子:
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class LinuxCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Linux"); } }
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class WindowsCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Windows"); } }
我们有两个类LinuxCondition 和WindowsCondition 。两个类都实现了Condtin接口,重载的方法返回一个基于操作系统类型的布尔值。
下面我们定义两个bean,一个符合条件另外一个不符合条件:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public 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才会被初始化。
新书推荐《JavaEE开发的颠覆者: Spring Boot实战》,涵盖Spring 4.x、Spring MVC 4.x、Spring Boot企业开发实战。
京东地址:http://item.jd.com/11894632.html
当当地址:http://product.dangdang.com/23926195.html
亚马逊地址:http://www.amazon.cn/图书/dp/B01D5ZBFUK/ref=zg_bsnr_663834051_6
淘宝地址:https://item.taobao.com/item.htm?id=528426235744&ns=1&abbucket=8#detail
或自己在京东、淘宝、亚马逊、当当、互动出版社搜索自选。