0

I'm trying to get some advice to execute. When I use annotation without parameters its do execute but when the annotation includes parameters it's not.

@Aspect
class  a{   
    @Pointcut("execution(@com.annotations.AnnotationName* *(..))")
    void someMethod() {}

    @Around("someMethod()")
    public Object aroundSomeMethod(ProceedingJoinPoint pjp) throws Throwable
    {
    // some code
    }
}

Annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationName
{
    public String someString();
    public boolean someBoolean();
}

The use of the annotation:

@AnnotationName(
        someString= "string",
        someBoolean = false
)
private void mycode()
{//code }
Gutiel67
  • 47
  • 3
  • Are you sure your pointcut is properly defined? I tried on my own and I get:`java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 54 execution(@com.annotations.AnnotationName* *(..))` – pleft Sep 01 '21 at 16:59
  • It's not the expression I really used, couldn't write the real path. But it do worked without parameters – Gutiel67 Sep 01 '21 at 17:54
  • 1
    So how we can help you if you don't post the real code? Please post a small meaningful example that replicates the behavior. – pleft Sep 01 '21 at 18:32
  • The number of annotation arguments is not the problem, but that you are trying to advise a private method, which is impossible with a proxy-based tool like Spring AOP. You need native AspectJ for advising private methods. – kriegaex Sep 02 '21 at 09:27
  • Please provide enough code so others can better understand or reproduce the problem. – Community Sep 04 '21 at 20:05

1 Answers1

1

Following aspect code would advice a target method annotated with @AnnotationName

@Component
@Aspect
public class SomeMethodAspect {

    @Pointcut("@annotation(annotationName) && within(so.qn69016852..*)")
    private void someMethod(AnnotationName annotationName) {}
    
    @Around("someMethod(annotationName)")
    public Object aroundSomeMethod(ProceedingJoinPoint pjp,AnnotationName annotationName) throws Throwable
    {
        System.out.println(annotationName.someString());
        System.out.println(annotationName.someBoolean());
        return pjp.proceed();
    }
}

Couple of corrections/observations .

  1. Spring AOP cannot advice a private method of a Spring bean. The mycode() method should be in a bean and ideally public. ( Refer )
  2. The Aspect should also be a spring bean. This can be achieved by annotating the aspect with @Component

Remember to limit the scope : https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#writing-good-pointcuts

You may also go through this answer from @kriegaex to understand why an @annotation has a global scope.

Update :

The code shared by OP also works with modifying a typo ( a space between the AnnotationName and * in the pointcut expression ) . The observations shared earlier holds good here as well.

@Component
@Aspect
public class SomeMethodAspect {

    @Pointcut("execution(@so.qn69016852.anno.AnnotationName * so.qn69016852..*.*(..))")
    private void someMethod() {}
    
    @Around("someMethod() && @annotation(annotationName)")
    public Object aroundSomeMethod(ProceedingJoinPoint pjp,AnnotationName annotationName) throws Throwable
    {
        System.out.println(annotationName.someBoolean());
        System.out.println(annotationName.someString());
        return pjp.proceed();
    }
}
R.G
  • 6,436
  • 3
  • 19
  • 28
  • While this is a correct answer to the question how to intercept annotatd methods with Spring AOP, it does not solve the OP's problem (advising a private method) as presented in the original question. See my comment under the question. – kriegaex Sep 02 '21 at 09:30
  • 1
    Assumption I took was , this is not the actual code ( OP hinted the same in one of his comment ) and the question is on spring-aop . I agree with you on the comments about advising private method and I did mention about that in this answer. Thanks for pointing out. – R.G Sep 02 '21 at 12:03
  • Oh, sorry, I didn't notice the remark about private methods in the middle of your answer. I thought the OP only posted a fake pointcuts, but an actual target method. Why would he manually change public to private when copying and pasting? So that was the actual issue. He just happened to use parameters in that method's annotation, falsely thinking that was the root cause of the problem, even though it is completely unrelated. – kriegaex Sep 02 '21 at 13:26
  • @kriegaex so how do you explain that without parameters, the advice is executing even though the method is private? – Gutiel67 Sep 02 '21 at 13:30
  • I don't explain it, because with Spring AOP it is impossible. You are either misinterpreting your log or unknowingly using native AspectJ. – kriegaex Sep 02 '21 at 15:50