0

I am using spring AOP, how can I get values from annotation, Here is my annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface ExecutionMethodProfiler 
{
    String value() default "defaultValue";;
}

here is my XML:

<aop:aspectj-autoproxy/>
    <aop:config>
        <aop:aspect ref="methodProfiler">
            <aop:pointcut id="serviceMethod" 
                expression="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and @annotation(com.test.profiler.ExecutionMethodProfiler)" />
            <aop:around pointcut-ref="serviceMethod" method="profile"/>
        </aop:aspect>
    </aop:config>

And this is my serviceMethod:

public void profile(ProceedingJoinPoint jointPoint) throws Throwable {}

as of now I can get the values by using this code:

MethodSignature signature = (MethodSignature) jointPoint.getSignature();
System.out.println(signature.getMethod().getAnnotation(ExecutionMethodProfiler.class).value());

I don't like it, is there a better way?

kriegaex
  • 63,017
  • 15
  • 111
  • 202
Michael Biniashvili
  • 500
  • 1
  • 12
  • 24

1 Answers1

0

First change your advice to take your annotation as an additional argument:

public void profile(
    ProceedingJoinPoint jointPoint,
    ExecutionMethodProfiler methodProfiler
) throws Throwable {}

Then bind the annotation to that argument in your pointcut:

<aop:around
    pointcut="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and @annotation(methodProfiler)"
    method="profile"
    arg-names="methodProfiler"
/>

I did not actually test it because I am a bit busy now, but this is basically how it works.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • I try it, and I am getting error: nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut – Michael Biniashvili Jan 22 '17 at 07:30
  • I have updated my answer so as to have the joinpoint parameter first in the method signature. In AspectJ it can be the first or last parameter, but maybe Spring is more picky here. Furthermore, please make sure that the parameter name is the same everywhere: pointcut, arg-names and method signature. Otherwise it cannot be bound. – kriegaex Jan 22 '17 at 09:28
  • If I update the method signature thin I am getting this exception: Constructor threw exception; nested exception is java.lang.IllegalStateException: Expecting to find 2 arguments to bind by name in advice, but actually found 1 arguments. – Michael Biniashvili Jan 22 '17 at 14:05
  • It would be easier to use an `@Around` annotation directly in your code and make the class an `@Aspect` instead of using old-fashioned XML configuration which also makes it hard to correlate a pointcut and its advice. But if you want to continue on this path, maybe something like `arg-names="joinPoint,methodProfiler"` helps. I have no idea. Probably it helps to either experiment or actually read the [Spring AOP manual](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html). – kriegaex Jan 22 '17 at 14:15
  • I am using xml configuration because I need to load this aspact only in performance/develop environment, I don't need this to be active in production, using the xml it's easier for me to chose when to load the aop – Michael Biniashvili Jan 22 '17 at 16:36