前言
最近在学习spring,抽空会将学习的知识总结下面,本文我们会接触spring 4的新功能:@Conditional注解。在之前的spring版本中,你处理conditions只有以下两个方法:
- 在3.1版本之前,你需要使用spring expression language
- 在3.1版本发布时,profiles被引入来处理conditions。
让我们分别看看以上两者,在来理解spring 4带来的@Conditional注解。
Spring Expression Language(SPeL)
SPeL的三元标识符(IF-THEN-ELSE)可以在spring配置文件中用来表达条件语句。
1
2
3
4
5
6
|
<bean id= "flag" >
<constructor-arg value= "#{systemProperties['system.propery.flag'] ?: false }" />
</bean>
<bean id= "bean" >
<property name= "property" value= "#{ flag ? 'yes' : 'no' }" />
</bean>
|
这个bean的属性依赖于flag的值,该值是使用外部属性注入的,这样bean就具有了动态的能力。
使用 Profiles
这是在spring 3.1引入的。像下面这样使用。
1
2
3
4
5
6
7
8
9
10
|
<!-- default configuration - will be loaded if no profile is specified -->
<!-- This will only work if it's put at the end of the configuration file -->
<!-- so no bean definitions after that -->
<beans profile= "default" >
< import resource= "classpath:default.xml" />
</beans>
<!-- some other profile -->
<beans profile= "otherProfile" >
< import resource= "classpath:other-profile.xml" />
</beans>
|
使用spring 4的@Conditional注解
现在介绍@Conditional注解。官方文档的说明是“只有当所有指定的条件都满足是,组件才可以注册”。主要的用处是在创建bean时增加一系列限制条件。
Conditional接口的声明如下:
1
2
3
4
5
|
@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE, ElementType.METHOD)
public @interface Conditional{
Class <!--? extends Condition-->[] value();
}
|
所以@Conditional注解使用方法如下
- 类型级别,可以在@Component 或是 @Configuration类上使用
- 原型级别,可以用在其他自定义的注解上
- 方法级别,可以用在@Bean的方法上
如果一个@Configuration类使用了@Conditional,会影响所有@Bean方法和@Import关联类
1
2
3
4
5
6
7
8
9
10
|
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);
}
|
下面是一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class SystemPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return (System.getProperty( "flag" ) != null );
}
}
class SystemPropertyAbsentCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return (System.getProperty( "flag" ) == null );
}
}
|
这里我们有两个类:SystemPropertyCondition和SystemPropertyAbsentCondtion. 这两个类都实现了Condition接口.覆盖的方法基于属性flag返回一个布尔值。
现在我们定义两个类,一个是positive条件,一个是negative条件:
1
2
3
4
5
6
7
8
9
10
11
|
@Bean
@Conditional (SystemPropertyCondition. class )
public SampleService service1() {
return new SampleServiceImpl1();
}
@Bean
@Conditional (SystemPropertyAbsentCondition. class )
public SampleService service2() {
return new SampleServiceImpl2();
}
|
上面提到的profiles已经通过conditional原型注解进行了修改。
总结
本文介绍了spring 4的conditianal注解。注意condition注解是不会继承的。如果一个父类使用了conditional注解,其子类是不会拥有conditions的。如果你动手尝试以上的例子,会帮助你获得更好的理解。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://segmentfault.com/a/1190000011033012