问题背景

在 Spring AOP 中,如果一个 bean 被代理,那么在目标 bean 内部,通过 AopContext.currentProxy() 可以获取到代理对象自身。有时候,我们希望在同一个 bean 的不同方法中调用对方时,调用的是代理方法并能够生效缓存。然而,直接在同一个类的不同方法中调用方法时,缓存可能并不生效。那么,我们如何使用 AopContext.currentProxy() 来解决这个问题呢?

解决方案

要解决缓存不生效的问题,可以使用以下的步骤:

步骤一:配置 Spring AOP

首先,在 Spring 配置文件中配置 AOP,确保目标 bean 被代理。如下所示:

<!-- 配置AOP -->
<aop:aspectj-autoproxy />

<!-- 配置目标bean -->
<bean id="targetBean" class="com.example.TargetBean" />
XML

步骤二:在目标 bean 类中使用 AopContext.currentProxy()

在目标 bean 类中的方法 A 中调用方法 B 时,使用 AopContext.currentProxy() 来获取代理对象,并在这个代理对象上调用方法 B。如下所示:

public class TargetBean implements Target {

    @Autowired
    private Target self;

    // 方法A
    @Override
    public void methodA() {
        Target proxy = (Target) AopContext.currentProxy();
        proxy.methodB(); // 在代理对象上调用方法B
    }

    // 方法B
    @Cacheable("cacheName")
    public void methodB() {
        // 执行业务逻辑
    }
}
Java

步骤三:设置 exposeProxy 为 true

为了使 AopContext.currentProxy() 能够返回代理对象,需要在 Aop 配置中将 exposeProxy 设置为 true,以便将代理对象暴露给 AopContext。如下所示:

<aop:config>
    <aop:aspect id="cacheAspect" ref="cacheAdvice">
        <!-- 设置exposeProxy为true -->
        <aop:pointcut id="targetBeanMethods" expression="execution(* com.example.TargetBean.*(..))" />
        <aop:around pointcut-ref="targetBeanMethods" method="addAdvice">
        </aop:around>
    </aop:aspect>
</aop:config>
XML

通过上述步骤,AopContext.currentProxy() 就能够返回正确的代理对象,从而解决了缓存不生效的问题。