Spring专题「实战系列」针对Spring注解@ConditionalOnExpression详细使用说明
Posted 洛神灬殇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring专题「实战系列」针对Spring注解@ConditionalOnExpression详细使用说明相关的知识,希望对你有一定的参考价值。
前提介绍
通过Spring框架进行判断的Bean,Class是否存在,配置参数是否存在或者有某个值而言,这个依赖SPEL表达式的,就显得更加的高级了;其主要就是执行Spel表达式,根据返回的true/false来判断是否满足条件。至于SPEL是什么东西,下面以一个简单的demo进行演示它的使用姿势。
@ConditionalOnExpression
接口定义
@Retention(RetentionPolicy.RUNTIME)
@Target( ElementType.TYPE, ElementType.METHOD )
@Documented
@Conditional(OnExpressionCondition.class)
public @interface ConditionalOnExpression
/**
* The SpEL expression to evaluate. Expression should return @code true if the
* condition passes or @code false if it fails.
* @return the SpEL expression
*/
String value() default "true";
实例测试
用一个简单的例子,当配置参数中,根据是否满足某个条件来决定是否需要加载bean
测试用例
定义一个满足条件和一个不满足的bean
public class ExpressFalseBean
private String name;
public ExpressFalseBean(String name)
this.name = name;
public String getName()
return "express bean :" + name;
public class ExpressTrueBean
private String name;
public ExpressTrueBean(String name)
this.name = name;
public String getName()
return "express bean :" + name;
采用#的方式进行分析配置
采用#通过environment的对象进行获取相关的配置信息key
@Configuration
public class ExpressAutoConfig
/**
* 当存在配置,且配置为true时才创建这个bean
* @return
*/
@Bean
@ConditionalOnExpression("#'true'.equals(environment['conditional.express'])")
public ExpressTrueBean expressTrueBean()
return new ExpressTrueBean("express true");
/**
* 配置不存在,或配置的值不是true时,才创建bean
* @return
*/
@Bean
@ConditionalOnExpression("#!'true'.equals(environment.getProperty('conditional.express'))")
public ExpressFalseBean expressFalseBean()
return new ExpressFalseBean("express != true");
对应的配置如下
conditional.express=true
实例演示
@RestController
@RequestMapping(path = "express")
public class ExpressRest
@Autowired(required = false)
private ExpressTrueBean expressTrueBean;
@Autowired(required = false)
private ExpressFalseBean expressFalseBean;
@GetMapping(path = "show")
public String show()
Map<String, String> result = new HashMap<>(4);
result.put("expressTrueBean", expressTrueBean == null ? "null ==> false" : expressTrueBean.getName());
result.put("expressFalseBean", expressFalseBean == null ? "null ==> true": expressFalseBean.getName());
return JSONObject.toJSONString(result);
采用$的方式进行分析配置
@ConditionalOnExpression("$mq.consumer.enabled==1&&$rabbitmq.comsumer.enabled:true")
@ConditionalOnExpression("'$mq.consumer'.equals('rabbitmq')")
解析配置类
使用@ConditionalOnExpression(“‘$task.enable’.equals(‘true’)”)这种方式的话,是可以的。由于这个配置在自定义的文件中,因此使用了
@PropertySource(value= "classpath:taskconfig.yml", ignoreResourceNotFound = true , factory = MixPropertySourceFactory.class)
引入配置文件。 MixPropertySourceFactory是自定义的类,用于加载yml类型的配置文件。
public class MixPropertySourceFactory extends DefaultPropertySourceFactory
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException
String sourceName = name != null ? name : resource.getResource().getFilename();
if (!resource.getResource().exists())
return new PropertiesPropertySource(sourceName, new Properties());
else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml"))
Properties propertiesFromYaml = loadYml(resource);
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
else
return super.createPropertySource(name, resource);
private Properties loadYml(EncodedResource resource) throws IOException
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
在application.properties
写如下配置就不会是实例化这个bean
database.isEmbedded:true
@Bean
@ConditionalOnExpression("!$database.isEmbedded:true")
public ConnectionPool dataSourceMBean(DataSourceProxy dataSourceProxy) throws SQLException
return dataSourceProxy.createPool().getJmxPool();
Condition注解使用
Spring提供了很多Condition给我们用,@ConditionalOnExpression表示基于SpEL表达式作为判断条件,这个组合了@Conditional元注解,只是使用了不同的条件(Conditional)
@Conditional,满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的。
首先,两个Condition,判断当前系统是否是Windows或者Linux(True False)
public class LinuxCondition implements Condition
@Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1)
return arg0.getEnvironment().getProperty("os.name").contains("Linux");
public class WindowsCondition implements Condition
@Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1)
return arg0.getEnvironment().getProperty("os.name").contains("Windows");
然后,2个ListService实现类,表明不同系统下的ListService实现。
public interface ListService
public String showListCmd();
public class LinuxListService implements ListService
@Override
public String showListCmd()
return "ls";
public class WindowsListService implements ListService
@Override
public String showListCmd()
return "dir";
然后ConditionConfig使用了Java配置与@Conditional注解,根据LinuxCondition,或者WindowsCondition作为判断条件
@Configuration
public class ConditionConfig
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService()
return new WindowsListService();
@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService()
return new LinuxListService();
最后,App.java 测试成功。
public class App
public static void main(String[] args)
ApplicationContext context = new AnnotationConfigApplicationContext(
ConditionConfig.class);
ListService ls = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name")
+ "系统下的列表命令为:" + ls.showListCmd());
参考资料
以上是关于Spring专题「实战系列」针对Spring注解@ConditionalOnExpression详细使用说明的主要内容,如果未能解决你的问题,请参考以下文章
#私藏项目实操分享#Spring专题「实战系列」spring注解@ConditionalOnExpression详细使用说明
#yyds干货盘点#Spring专题「实战系列」Spring Security原理以及实战认证分析开发指南
深入浅出Spring原理及实战「开发实战系列」Spring-Cache扩展自定义(注解失效时间+主动刷新缓存)