仅当从某个 class 调用该方法时才拦截该方法?

Intercept a method only if that method is called from a certain class?

使用 AspectJ 或 Spring Aop(无关紧要),是否仅当从某个 class 中调用该方法时才可能拦截该方法?

示例:

public class House() {

    String address;

    public House(String address) {
       this.address = address;
    }   
   
    public String getAddress() {
      return this.address();
   }
}


public class BadHouse() {

    public void doNotIntercept() {
      House h = new House("1234");
      h.getAddress();
   }
}

public class GoodHouse() {
     
     public void intercept() {
     House h = new House("4567");
     h.getAddress();
    }

}

public class houseInterceptor() {

     @Before("execution(com.example.House.getAddress(..))")
     // only intercept on GoodHouse.class??? 
     public void beforeGetAddress();

}

这种情况下可以用within吗? 谢谢

using AspectJ or Spring Aop (doesn't matter), is it possible to intercept a method only if that method is called from within a certain class?

AspectJ 可以(是否在 Spring 内使用,这无关紧要),但 Spring AOP 不行,因为你需要

  • 使用 call() 切入点和 JoinPoint.EnclosingStaticPart(注释样式)或 thisEnclosingJoinPointStaticPart(本机语法)的组合,当且仅当您要检查直接调用者时,
  • 或者使用 call() 切入点和 this() 的组合,再次当且仅当你想检查直接调用者时,
  • 或使用 call()execution()cflow()cflowbelow() 切入点的组合,如果你想检查可能的间接调用者(例如 GoodHouseFooHouse).

上述所有方法仅在 AspectJ 中有效的原因是 Spring AOP 既不支持 call() 也不支持 cflow(),如文档 here.

Can "within" be used in this circumstance?

不,within() 在这种情况下对您没有帮助。


更新: 此处引用我的其他答案:

  • call() + JoinPoint.EnclosingStaticPart
  • call() + this()
  • ,可以选择与 this() 结合使用,还展示了如何使用 thisEnclosingJoinPointStaticPart

更新 2: 更未知的角落或 Spring AOP 之一是 ControlFlowPointcut class. The Spring manual mentions it briefly without example, but there is a test in the Spring source code and I found an example on a 3rd-party website。它不能帮助你直接解决你的问题,但我可以想到一个解决方案,在这个解决方案中,你为每个允许的源创建一个这样的切入点 class 和 link 每个切入点到实现方面的同一个顾问你想要的行为。这会很慢,因为 Spring 使用反射和调用堆栈,需要一些样板代码来手动连接所有内容,但它可以工作。