Lewis Wong
Lewis Wong

Reputation: 269

Unable to retrieve annotation via ProceedingJoinPoint

I would like to retrieve an annotation from AOP join point. I am able to get the annotation by reflection, but unable to do so with ProceedingJoinPoint.

If the method isn't annotated with Profile, the advise would not be invoked... but inside the advise, it couldn't locate the annotation.

By ProceedingJoinPoint

@Around("@annotation(com.annotation.Profile)")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    Signature signature = joinPoint.getSignature();
    String methodName = signature.toString();
    Method method = ((MethodSignature) signature).getMethod();

    Profile profile = method.getAnnotation(Profile.class);

    // profile is null here...
    // ......

}   

By reflection directly

public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    Method method = SampleServiceImpl.class.getMethod("getTicket", String.class);
    System.out.println(method.getClass().toString());
    System.out.println(method.getAnnotation(Profile.class));
}

My Annotation

@Documented
@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Profile {
    public long skipCount();
    public long sampleSize();
}

My Annotated method

@Override
@Cacheable("test")
@Transactional
@Profile(skipCount = 100, sampleSize = 100)
public Tickets getTicket(String ticketId) {
    return sampleDao.getTicket(ticketId);
}

My POM

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jdk.version>1.8</jdk.version>
    <spring.version>4.1.1.RELEASE</spring.version>
    <aspectj.version>1.8.3</aspectj.version>
</properties>

<!-- Spring AOP + AspectJ -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

Upvotes: 1

Views: 1009

Answers (1)

kriegaex
kriegaex

Reputation: 67327

There is no need for reflection, it is much easier. You can bind the annotation to an advice parameter:

@Around("@annotation(profileAnnotation)")
public Object logAround(Profile profileAnnotation, ProceedingJoinPoint thisJoinPoint) throws Throwable {
    System.out.println(thisJoinPoint + " - " +  profileAnnotation);
    // (...)
    Object result = thisJoinPoint.proceed();
    // (...)
    return result;
}

The console output could be something like this:

execution(void de.scrum_master.app.Application.main(String[])) - @de.scrum_master.app.Profile(skipCount=5, sampleSize=11)

Upvotes: 2

Related Questions