Spring Expression Language en anotaciones personalizadas

Quiero usar Spring Expression Language en una anotación personalizada. Esta anotación será consumida por un aspecto personalizado.

Miren esto:

@StatisticEventTrigger(value = TestStatisticEvent.class, expression = "#p1")
public void someOtherMethod(String arg1, Long arg2) {

Como puede ver, quiero usar la expresión (en este caso) para recuperar algún argumento específico.

Cuando tengo mi Aspecto, activando un método anotado, me gustaría evaluar la expresión de primavera (mediante programación) para recuperar un valor para usar en otras cosas comerciales;)

¿Algunas ideas? ¡Google no era mi amigo hasta ahora!

preguntado el 03 de diciembre de 13 a las 12:12

Deja que Spring inyecte ExpressionParser a tu aspecto. Usarlo es bastante sencillo. docs.spring.io/spring/docs/3.2.x/javadoc-api/org/… -

¿Y cómo sería la expresión? ¿Puedes publicar un breve ejemplo? -

Tengo que corregir el comentario anterior, solo crea SpelExpressionParser manualmente y siga las instrucciones detalladas en la documentación de referencia. Hay más que muchos ejemplos. docs.spring.io/spring/docs/3.0.x/reference/expresiones.html -

1 Respuestas

Descubrí cómo hacerlo con SpEL. Usé la siguiente expresión:

@EventTrigger(value = EventTestModel.class, expression = "new Object[]{arguments[1], arguments[2]}")

y siguiente código Java:

ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(expressionEvaluationTarget);
Object[] eventPayloadModels = parser.parseExpression(expression).getValue(context);

Funciona bien ;)

ACTUALIZACIÓN

Aquí hay un ejemplo de código completo ahora:

import com.example.AbstractEvent;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.StringUtils;

public class AnnotationEventTriggerAspect implements MethodInterceptor {
private static final Logger LOG = Logger.getLogger(AnnotationEventTriggerAspect.class);

private IEventHandler eventHandler;

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
    if (LOG.isDebugEnabled()) {
        LOG.debug("Invoking event event trigger for method: " + invocation.getMethod().getDeclaringClass() + "." + invocation.getMethod().getName());
    }

    EventTrigger annotation = invocation.getMethod().getAnnotation(EventTrigger.class);
    Class<? extends AbstractEvent> eventClass = annotation.value();

    if (eventClass == null) {
        throw new IllegalArgumentException("No event class provided for event event trigger annotation at method " + invocation.getMethod().getDeclaringClass() + "." + invocation.getMethod());
    }

    AbstractEvent event = eventClass.newInstance();
    String expression = annotation.expression();

    Object result = invocation.proceed();
    Object expressionEvaluationTarget = invocation;
    Object eventPayloadModels = invocation.getArguments();

    if (annotation.useResult()) {
        expressionEvaluationTarget = result;
        eventPayloadModels = new Object[]{result};
    }

    if (StringUtils.hasText(expression)) {
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(expressionEvaluationTarget);
        eventPayloadModels = parser.parseExpression(expression).getValue(context);
    }

    if (eventPayloadModels != null) {
        if (eventPayloadModels.getClass().isArray()) {
            for (Object arg : (Object[]) eventPayloadModels) {
                event.addPayloadModel(arg);
            }
        } else {
            event.addPayloadModel(eventPayloadModels);
        }
    }

    eventHandler.post(event);

    return result;
}

public IEventHandler getEventHandler() {
    return eventHandler;
}

public void setEventHandler(IEventHandler eventHandler) {
    this.eventHandler = eventHandler;
}

}

respondido 03 mar '17, 16:03

Agregando a esa respuesta útil, que para usarlo en los objetos de destino que son proxy de Spring, necesitaría extraer el objeto de destino real del proxy: stackoverflow.com/questions/8121551/… - Shlomi Uziel

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.