能否在Spring表达式语言(SpEL)的@ConditionalOnExpression中使用lambda?
在@ConditionalOnExpression中用SpEL实现类似Java anyMatch的简洁写法
首先明确:SpEL本身不支持Java原生的lambda箭头语法(->)的直接写法,但可以通过调用集合流的anyMatch()方法,并结合SpEL的表达式谓词,实现和Java中anyMatch(lambda)等价的简洁效果。
优化后的SpEL表达式
你可以将原表达式改写为以下形式,逻辑和你给出的Java代码完全一致:
@ConditionalOnExpression("#{T(java.util.Arrays).stream('${app.sync.white-list:}'.split(',')).anyMatch(#x -> #x.equalsIgnoreCase('all') || #x.equalsIgnoreCase('phone'))}")
关键说明:
- 用
'${app.sync.white-list:}'.split(',')替代原有的asList:如果配置值为空,split(',')会返回包含空字符串的数组,加上:(冒号加空格)可以让配置默认值为空字符串,避免空指针问题。 - SpEL中调用
anyMatch()时,通过#x -> ...的语法传递谓词表达式:这里的#x是SpEL中的变量,代表流中的每个元素,逻辑和Java lambda中的x完全一致。 - 相比原表达式的集合选择后判断
size()>0,anyMatch()会在匹配到第一个符合条件的元素时立即终止,性能更优,写法也更贴近你熟悉的Java逻辑。
补充:如果配置值本身是集合类型
如果你的app.sync.white-list配置本身是Spring支持的集合类型(比如在配置文件中用[]包裹),可以进一步简化为:
@ConditionalOnExpression("#{${app.sync.white-list}.stream().anyMatch(#x -> #x.equalsIgnoreCase('all') || #x.equalsIgnoreCase('phone'))}")
内容的提问来源于stack exchange,提问作者Mikhail Geyer
相关产品推荐
相关产品推荐

