如何跟踪一个不是从代理bean调用而是从bean调用的成员函数?

时间:2012-07-05 13:33:08

标签: java spring aop spring-aop

我有一个在我的网络应用程序中使用Spring AOP框架的类,就像下面显示的代码一样。我想知道为什么Spring AOP能够跟踪add()但是如果我实现以下代码则无法跟踪multiple()。

public interface calculator {
   public void add();
   public void multiple();
}

public class calculatorImpl implements calculator {

   public void add() {

      multiple();
   }

   public void multiple() {}
}

我做了一个实验,发现以下代码运行正常。这意味着Spring AOP能够跟踪添加和多功能。

ICalculator calcProxy = (ICalculator) context.getBean("calculatorProxy");
calcProxy.add();
calcProxy.multiple();

我认为必须由代理bean注入multiple(),而multiple()类中的calculatorImpl不是,因此Spring AOP无法跟踪它。如果我错了,请纠正我。

我的下一个问题。有没有解决这个问题,add()真的需要执行multiple()并获得Spring AOP的跟踪?

1 个答案:

答案 0 :(得分:2)

Spring AOP不会更改实际方法,但会在Object周围添加代理。一旦进入内部对象(在add()方法内),就没有代理,你就在它下面。

我在过去的答案中更详细地解释了这个机制:

https://stackoverflow.com/a/4171649/342852

有三种方法可以解决这种情况:

  1. 使用AspectJ,而不是Spring AOP。 AspectJ将行为编译到您的代码中,而Spring AOP使用代码周围的代理。
  2. 从Bean内部访问代理服务器。这非常丑陋,但可以做到 示例代码(在这里你让类知道它被代理,这与AOP所代表的一切相反):

    public void add() {
       ((Calculator)AopContext.currentProxy()).multiple();
    }
    

    稍微不那么可怕(在这里你让班级意识到它是由Spring管理的):

    @Autowired
    private ApplicationContext context;
    public void add() {
       context.getBean(Calculator.class).multiple();
    }
    
  3. 更改您的设计。示例:将两个方法移动到单独的bean中,并将每个方法注入另一个bean。