同一个类调用在 Spring AOP cglib 中无效 [英] Same class invoke NOT effective in Spring AOP cglib

查看:61
本文介绍了同一个类调用在 Spring AOP cglib 中无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下课程

@Service
class MyClass {

    public void testA() { 
        testB();
     }

    @Transactional
    public void testB() { ... }
}

现在,如果我们在测试中调用myClass.testA();,那么@TransactionaltestB 将不会生效.我认为原因如下.

Now, if we invoke myClass.testA(); in test, then @Transactional on testB will not take effect. The reason I think is following.

Cglib 将为 MyClass 创建一个代理 bean,如下所示:

Cglib will create a proxy bean for MyClass, like this:

Class Cglib$MyClass extends MyClass {

    @Override
    public void testB() {
        // ...do transactional things
        super.testB();
    }
}

现在我们调用 myClass.testA(),它将调用 MyClass.testB() 而不是 Cglib$MyClass.testB().所以 @Transactional 是无效的.(我说得对吗?)

Now we invoke myClass.testA(), which will invoke MyClass.testB() instead of Cglib$MyClass.testB(). So @Transactional is not effective. (Am I right?)

我尝试为两种方法(即 testA()testB())添加 @Transactional.代理类应该是这样的.

I tried to add @Transactional for both methods (i.e. testA() and testB()). The proxy class should like this.

Class Cglib$MyClass extends MyClass {

    @Override
    public void testA() {
        // ...do transactional things
        super.testA();
    }

    @Override
    public void testB() {
        // ...do transactional things
        super.testB();
    }
}

在这种情况下,虽然我们成功调用了Cglib$MyClass.testA(),但它仍然会转到MyClass.testB().

In this case, although we successfully invoke Cglib$MyClass.testA(), it will still goes to MyClass.testB().

所以我的结论是,同一个类中的两个方法相互调用会导致aop注解失效,除非我们使用AopContext.currentProxy().

So my conclusion is, two methods in same class invoking each other will make aop annotation fail to take effect, unless we use AopContext.currentProxy().

我猜对了吗?非常感谢您的建议!

Am I right on above guess? Thanks very much for advice!

推荐答案

是一个众所周知的记录(请搜索术语自调用")Spring AOP 的事实,由于其基于代理的性质, 不会也不能捕获像 this.someMethod(..) 这样的内部方法调用.

It is a well-known and documented (please search for the term "self-invocation") fact that Spring AOP, due to its proxy-based nature, does not and cannot capture internal method calls like this.someMethod(..).

如您所说,您要么需要明确引用公开的代理对象,要么从 Spring AOP 切换到完整的 AspectJ 通过加载时编织.

So as you said, you either need to explicitly refer to the exposed proxy object or alternatively switch from Spring AOP to full AspectJ via load-time weaving.

这篇关于同一个类调用在 Spring AOP cglib 中无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆