Java Spring 4.2+;:如何从@EventListener条件表达式中引用Springbean实例
在Spring4.2+中,我们可以使用@EventListener注释和“条件”表达式 在我的场景中,我需要将事件对象的id与在.properties文件中配置的正则表达式相匹配 然而,似乎不可能从条件的正则表达式引用任何bean的属性或方法,因为根上下文似乎就是事件对象本身 到目前为止,我有一个抽象类,它根据类名设置事件id模式属性。目标是使每个事件侦听器的实现尽可能干净和简单Java Spring 4.2+;:如何从@EventListener条件表达式中引用Springbean实例,java,spring,spring-el,spring-bean,Java,Spring,Spring El,Spring Bean,在Spring4.2+中,我们可以使用@EventListener注释和“条件”表达式 在我的场景中,我需要将事件对象的id与在.properties文件中配置的正则表达式相匹配 然而,似乎不可能从条件的正则表达式引用任何bean的属性或方法,因为根上下文似乎就是事件对象本身 到目前为止,我有一个抽象类,它根据类名设置事件id模式属性。目标是使每个事件侦听器的实现尽可能干净和简单 @Service @PropertySource(value = "classpath:subscriberEven
@Service
@PropertySource(value = "classpath:subscriberEventMapping.properties")
public abstract class AbstractEventHandler implements IEventHandler {
private String eventIdPattern;
@Autowired
Environment env;
@Autowired(required = true)
public void configureEventIdPattern() {
String simpleClassName = this.getClass().getSimpleName();
String resolvedEventIdPattern = env.getProperty(
simpleClassName.substring(0,1).toLowerCase() +
simpleClassName.substring(1, simpleClassName.length()));
this.eventIdPattern = resolvedEventIdPattern == null ? ".*" : resolvedEventIdPattern;
}
public String getEventIdPattern() {
return eventIdPattern;
}
}
属性文件如下所示:
regExpEventHandler=^(901|909|998|1000)$
dummyEventHandler=^([1-9][0-9]{0,2}|1000)$
然后,我有一个扩展上述抽象类的示例事件侦听器:
@Service
public class RegExpEventHandler extends AbstractEventHandler {
@Log
private ILog logger;
@Override
@EventListener(condition = "#event.eventid matches @regExpEventHandler.getEventIdPattern()")
public void onEvent(Event event) {
logger.debug("RegExpEventHandler processing : {} with event pattern : {}", event, getEventIdPattern());
}
}
问题是这个表达式
“#event.eventid与@regExpEventHandler.getEventIdPattern()匹配”
无法工作,因为在@EventListener使用的上下文中找不到bean“@RegeExpEventHandler”
这里有没有访问现有Springbean的方法或属性的方法?对于这种情况,还有其他更好的方法吗
我知道我可以通过以下方式轻松访问静态常量或方法:
#event.eventid matches T(my.package.RegExpEventHandler.MY_CONSTANT)
但是不能使用@Value表达式从属性文件初始化字符串常量(静态最终值)
使用非最终静态常量可以工作,但是每个事件侦听器都需要添加boiler plate,以便使用@Value表达式从非静态变量初始化静态常量,这是我们想要避免的
提前多谢 它对我有效-我查看了
EventExpressionEvaluator
,发现它在评估上下文中添加了一个bean解析器
public EvaluationContext createEvaluationContext(ApplicationEvent event, Class<?> targetClass,
Method method, Object[] args, BeanFactory beanFactory) {
Method targetMethod = getTargetMethod(targetClass, method);
EventExpressionRootObject root = new EventExpressionRootObject(event, args);
MethodBasedEvaluationContext evaluationContext = new MethodBasedEvaluationContext(
root, targetMethod, args, getParameterNameDiscoverer());
if (beanFactory != null) {
evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
return evaluationContext;
}
而且效果很好
bar:org.springframework.context.PayloadApplicationEvent[...
handler:foo
(这是4.3.7版本;boot 1.5.2版本)。为什么
regExpEventHandler
会是一个bean?这是一个属性而不是一个bean…不确定我是否遵循。。。我的理解是,在Spring EL表达式中,可以使用@引用bean。我还尝试了一些更简单的方法,比如#event.eventid匹配${regExpEventHandler},它应该从属性文件中获取相应的值,但是表达式也失败了Yes beans,但是您尝试将属性引用为不起作用的bean。啊,您正在引用自己。首先,我认为您的@Autowired
应该是一个@PostConstruct
。尝试其他方法,如“#event.eventid匹配$regExpEventHandler”,希望从.properties文件中获取相应的属性,会产生错误:org.springframework.expression.spel.SpelEvaluationException:EL1008E:(pos 23):在类型为“org.springframework.context.event.EventExpressionRootObject”的对象上找不到属性或字段“$regExpEventHandler”-可能不是公共的?我正在尝试类似的方法,但到目前为止没有任何效果…非常感谢Gary的帮助。。。我们正在使用Spring4.2.6,我刚刚发现在这个版本中,EventExpressionEvaluator没有bean解析器。。。所以我头疼。。。我很确定切换到4.3.7可能会解决问题。。。再次非常感谢!切换到4.3.7后工作正常。。。非常感谢!
bar:org.springframework.context.PayloadApplicationEvent[...
handler:foo