为什么 Spring AOP 在某些情况下会拦截受保护的方法?
Why does Spring AOP intercept protected methods under certain circumstances?
我读到 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*
存在时拦截。
谁能解释一下为什么会这样?
Can anyone explain me why this is happening?
由于 Spring 的 AOP 框架基于代理的性质,根据定义,受保护的方法不会被拦截,无论是对于 JDK 代理(这不适用)还是对于 CGLIB代理(这在技术上是可行的,但不推荐用于 AOP 目的)。
因此,任何给定的切入点都将仅与 public 方法匹配!
如果您的拦截需要包括 protected/private 方法甚至构造函数,请考虑使用 Spring 驱动的原生 AspectJ 编织,而不是 Spring 基于代理的 AOP 框架。
When this code is executed both getName and getNamesprotected are
intercepted
@Before("execution(* com.tutorialspoint.Student.*Name*(..))")
此处前面的通配符匹配具有任何修饰符(public、protected 和 private)和任何 return 类型的方法。参数列表中的两个点匹配任意数量的参数。
试试这个它应该执行你的受保护方法
@Pointcut("execution(protected * *.*(..))")
如果它适合你,你也可以试试这个(我不是 100% 确定)
@Before("execution(* com.tutorialspoint.Student+.getNamesprotected(..))")
因为 OP (Prateek Gupta) 似乎无法(相当不愿意)创造一点 SSCCE 重现问题,而我只是在茶歇期间感到无聊,所以我很快用 Spring 启动并且非常惊讶确实 Spring AOP,与文档相矛盾,至少在某些情况下,当涉及 CGLIB 代理时,它与受保护的方法相匹配。
因此,我为 Spring 的 Jira 问题跟踪器注册了一个帐户,并将此回归报告为 SPR-15354。如果对 Spring 开发团队的回答感兴趣,您可能想要订阅该票证的更新。
更新: 回复我的工单的人告诉我这是文档问题。正如 2006 年的 SPR-1611 告诉我们的那样,这已经在 Spring 1.2.7 中有意更改,但从未在文档中找到它的方式。底线:受保护的方法可以通过 Spring AOP 捕获,这不是偶然的,但已经 12 年没有记录了。
更新 2: 更新的文档文本将在下一个 Spring 版本中。今天要看固定文,引用在SPR-1611.
我读到 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*
存在时拦截。
谁能解释一下为什么会这样?
Can anyone explain me why this is happening?
由于 Spring 的 AOP 框架基于代理的性质,根据定义,受保护的方法不会被拦截,无论是对于 JDK 代理(这不适用)还是对于 CGLIB代理(这在技术上是可行的,但不推荐用于 AOP 目的)。
因此,任何给定的切入点都将仅与 public 方法匹配!
如果您的拦截需要包括 protected/private 方法甚至构造函数,请考虑使用 Spring 驱动的原生 AspectJ 编织,而不是 Spring 基于代理的 AOP 框架。
When this code is executed both getName and getNamesprotected are intercepted
@Before("execution(* com.tutorialspoint.Student.*Name*(..))")
此处前面的通配符匹配具有任何修饰符(public、protected 和 private)和任何 return 类型的方法。参数列表中的两个点匹配任意数量的参数。
试试这个它应该执行你的受保护方法
@Pointcut("execution(protected * *.*(..))")
如果它适合你,你也可以试试这个(我不是 100% 确定)
@Before("execution(* com.tutorialspoint.Student+.getNamesprotected(..))")
因为 OP (Prateek Gupta) 似乎无法(相当不愿意)创造一点 SSCCE 重现问题,而我只是在茶歇期间感到无聊,所以我很快用 Spring 启动并且非常惊讶确实 Spring AOP,与文档相矛盾,至少在某些情况下,当涉及 CGLIB 代理时,它与受保护的方法相匹配。
因此,我为 Spring 的 Jira 问题跟踪器注册了一个帐户,并将此回归报告为 SPR-15354。如果对 Spring 开发团队的回答感兴趣,您可能想要订阅该票证的更新。
更新: 回复我的工单的人告诉我这是文档问题。正如 2006 年的 SPR-1611 告诉我们的那样,这已经在 Spring 1.2.7 中有意更改,但从未在文档中找到它的方式。底线:受保护的方法可以通过 Spring AOP 捕获,这不是偶然的,但已经 12 年没有记录了。
更新 2: 更新的文档文本将在下一个 Spring 版本中。今天要看固定文,引用在SPR-1611.