Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

335
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda