Spring Expression Language en anotaciones personalizadas
Frecuentes
Visto 10,000 veces
13
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!
1 Respuestas
5
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 java spring aop spring-el or haz tu propia pregunta.
Deja que Spring inyecte
ExpressionParser
a tu aspecto. Usarlo es bastante sencillo. docs.spring.io/spring/docs/3.2.x/javadoc-api/org/… - Pavel Horal¿Y cómo sería la expresión? ¿Puedes publicar un breve ejemplo? - goosefraba
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 - Pavel Horal