I need to set some of my fields in the annotated interface to accept Spring expression language definitions.
I have a working code, but I am not satisfied with this. See:
Annotation:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Example {
String id();
}
Aspect:
@Aspect
@Component
public class ExampleAspect {
@Before("@annotation(com.example.annotation.Example)")
public void beforeAdvice(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Example p = signature.getMethod().getAnnotation(Example.class);
long id = (Long) valueFromExpression(joinPoint, p.id());
// .... work with ID
}
/**
* Manually processed SpEL expression
*/
private Object valueFromExpression(JoinPoint joinPoint, String expression) {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();
String[] parameterNames = codeSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
Expression exp = parser.parseExpression(expression);
return exp.getValue(context);
}
}
Usage:
@GetMapping("/test/{someId}")
@Example(id = "#someId")
public void example(@PathVariable Long someId) {
// some code
}
This works, but I want to define initialization of annotation properties as automatically processed by SpEL and also properly highlighted by my IDE - without method valueFromExpression()