Why does Spring AOP intercept protected methods un

2020-07-16 06:30发布

问题:

I read that Spring AOP cannot intercept private and protected methods but it is intercepting them in a weird way why is that?

I have these functions i want to intercept:

public String getName(String string) {
   System.out.println("Name : " + name + string);
   return name;
}

protected String getNamesprotected(String string) {
  System.out.println("Name : " + name + string);
  return name;
}

This is my @Aspect code:

@Aspect
public class Logging {

    @Before("execution(* com.tutorialspoint.Student.*Name*(..))")
    public void beforeAdvice(JoinPoint joinPoint){
       System.out.println("Going to setup student profile."+joinPoint.getSignature().toString());
    }
}

When this code is executed both getName and getNamesprotected are intercepted but when I execute this code :

@Aspect
public class Logging {

    @Before("execution(* com.tutorialspoint.Student.getNamesprotected(..))")
    public void beforeAdvice1(JoinPoint joinPoint){
       System.out.println("Going to setup student profile."+joinPoint.getSignature().toString());
    }
}

Then nothing is intercepted. I also tried replacing getNamesprotected with *getNamesprotected* but still it does not intercept. It only intercepts when *Name* is there.

Can anyone explain me why this is happening?

回答1:

Because the OP (Prateek Gupta) seemed to be unable (rather unwilling) to create a little SSCCE reproducing the problem and I was just bored during a tea break, I quickly created one by myself with Spring Boot and was very surprised that indeed Spring AOP, in contradiction to the documentation, at least under certain circumstance matches against protected methods when CGLIB proxies are involved.

Thus, I registered myself an account for Spring's Jira issue tracker and reported this regression as SPR-15354. You might want to subscribe for updates on that ticket if interested in answers by the Spring development team.


Update: The person answering to my ticket told me that this is a documentation issue. As SPR-1611 from 2006 tells us, this was already changed on purpose for Spring 1.2.7 but has never found its way into the documentation. Bottom line: Protected methods can be captured via Spring AOP, it is not an accident but has been undocumented for 12 years.


Update 2: The updated documentation text will be in the next Spring release. If you want to read the fixed text today, it is quoted in SPR-1611.



回答2:

Can anyone explain me why this is happening?

Due to the proxy-based nature of Spring’s AOP framework, protected methods are by definition not intercepted, neither for JDK proxies (where this isn’t applicable) nor for CGLIB proxies (where this is technically possible but not recommendable for AOP purposes).

As a consequence, any given pointcut will be matched against public methods only!

If your interception needs include protected/private methods or even constructors, consider the use of Spring-driven native AspectJ weaving instead of Spring’s proxy-based AOP framework.

When this code is executed both getName and getNamesprotected are intercepted

 @Before("execution(* com.tutorialspoint.Student.*Name*(..))")

Here the preceding wildcard matches methods with any modifier (public, protected, and private) and any return type. The two dots in the argument list match any number of arguments.

Try this it should execute your protected method

@Pointcut("execution(protected * *.*(..))")

Also you can try this if it works for you (I am not 100% sure)

 @Before("execution(* com.tutorialspoint.Student+.getNamesprotected(..))")