我读到Spring AOP无法拦截私有和受保护的方法,但它以奇怪的方式拦截它们为什么会这样?
我想拦截这些功能:
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;
}
这是我的@Aspect
代码:
@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());
}
}
执行此代码时,getName和getNamesprotected都会被拦截,但是当我执行此代码时:
@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());
}
}
然后没有截获任何内容。我还尝试用getNamesprotected
替换*getNamesprotected*
,但仍然没有拦截。它仅在*Name*
出现时截获。
任何人都可以解释为什么会这样吗?
答案 0 :(得分:6)
因为OP(Prateek Gupta)似乎无法(相当不愿意)创建一个小SSCCE来重现这个问题,而我在茶歇期间感到很无聊,我很快就用Spring Boot自己创建了一个非常惊讶Spring AOP确实与文档相矛盾,至少在某些情况下,当涉及CGLIB代理时,与受保护方法相匹配。
因此,我为自己注册了Spring的Jira问题跟踪器帐户,并将此回归报告为SPR-15354。如果对Spring开发团队的答案感兴趣,您可能希望订阅该票证的更新。
更新:回复我的机票的人告诉我这是一个文档问题。正如2006年SPR-1611告诉我们的那样,这已经在Spring 1.2.7中有意改变,但从未在文档中找到过。底线:受保护的方法可以通过Spring AOP捕获,这不是一个意外,但已经没有记录了12年。
更新2:更新的文档文本将在下一个Spring版本中发布。如果您想今天阅读固定文字,请在SPR-1611中引用。
答案 1 :(得分:2)
任何人都可以解释为什么会这样吗?
由于Spring的AOP框架基于代理的特性,根据定义,受保护的方法既不是针对JDK代理(这不适用),也不针对CGLIB代理(这在技术上可行,但不建议用于AOP)目的)。
因此,任何给定的切入点都只与公共方法匹配!
如果您的拦截需要包括受保护/私有方法甚至构造函数,请考虑使用Spring驱动的本机AspectJ编织而不是Spring的基于代理的AOP框架。
执行此代码时,getName和getNamesprotected都是 截获
@Before("execution(* com.tutorialspoint.Student.*Name*(..))")
这里前面的通配符将方法与任何修饰符(public,protected和private)以及任何返回类型匹配。参数列表中的两个点匹配任意数量的参数。
试试这个应该执行受保护的方法
@Pointcut("execution(protected * *.*(..))")
如果它对您有用,我也可以试试(我不是100%肯定)
@Before("execution(* com.tutorialspoint.Student+.getNamesprotected(..))")