Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

332
Views
Spring 4.2+: cómo hacer referencia a una instancia de Spring Bean desde dentro de una expresión de condición @EventListener

En Spring 4.2+, podemos usar la anotación @EventListener con una expresión de "condición".

En mi escenario, necesito hacer coincidir la identificación del objeto de evento con una expresión regular que está configurada en un archivo .properties.

Sin embargo, parece imposible hacer referencia a cualquier propiedad o método de bean desde la expresión regular de la condición, ya que el contexto raíz parece ser el objeto de evento en sí.

Hasta ahora, tengo una clase abstracta que establece la propiedad del patrón de identificación del evento en función del nombre de la clase. El objetivo es hacer que la implementación de cada Event Listener sea lo más limpia y simple posible.

 @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; } }

El archivo de propiedades se ve así:

 regExpEventHandler=^(901|909|998|1000)$ dummyEventHandler=^([1-9][0-9]{0,2}|1000)$

Y luego, tengo un detector de eventos de muestra que amplía la clase abstracta anterior:

 @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()); } }

El problema es que la expresión

"#event.eventid coincide con @regExpEventHandler.getEventIdPattern()"

no funciona, porque el bean "@regExpEventHandler" no se puede encontrar en el contexto utilizado por @EventListener.

¿Hay alguna forma de acceder a los métodos o propiedades de un Spring Bean existente aquí? ¿Algún otro enfoque mejor para este escenario?

Sé que puedo acceder fácilmente a constantes o métodos ESTÁTICOS usando algo como:

 #event.eventid matches T(my.package.RegExpEventHandler.MY_CONSTANT)

Pero una constante de cadena (final estática) no se puede inicializar desde un archivo de propiedades usando una expresión @Value.

El uso de constantes estáticas NO FINALES puede funcionar, pero luego CADA Event Listener necesita agregar una placa estándar para inicializar la constante estática de una variable no estática usando una expresión @Value, que queremos evitar.

Muchas gracias por adelantado !

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Funciona para mí: miré EventExpressionEvaluator y vi que agregó un solucionador de beans al contexto de evaluación ...

 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; }

Así que escribí una prueba rápida...

 @SpringBootApplication public class So43225913Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(So43225913Application.class, args); context.publishEvent("foo"); } @EventListener(condition = "@bar.accept(event)") public void listen(Object event) { System.out.println("handler:" + event); } @Bean public Bar bar() { return new Bar(); } public static class Bar { public boolean accept(Object o) { System.out.println("bar:" + o); return true; } } }

Y funciona bien...

 bar:org.springframework.context.PayloadApplicationEvent[... handler:foo

(Esto fue con 4.3.7; arranque 1.5.2).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!