AopContext.currentProxy()如何解决cache不生效问题
问题描述
在使用Spring AOP进行方法缓存的时候,使用AopContext.currentProxy()
获取当前代理对象,但发现缓存不生效。
问题分析
缓存不生效的原因是AopContext.currentProxy()
获取的并不是代理对象,而是目标对象本身。因此,不能直接在目标对象的方法内部调用被代理的方法,这样缓存并不会起作用。
解决方案
为了使方法缓存生效,可以通过以下几种方式解决:
方式一:使用代理对象调用方法
直接使用代理对象调用方法,而不是在目标对象的方法内部调用。
public class MyService {
// 使用代理对象调用方法
public void doSomething() {
((MyService) AopContext.currentProxy()).cachedMethod();
}
// 需要被代理的方法,添加缓存注解
@Cacheable("myCache")
public void cachedMethod() {
// 方法体
}
}
// 配置AOP
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
// 需要开启ExposeProxy,以便使用AopContext.currentProxy()
@Bean
public AspectJProxyFactory aspectJProxyFactory() {
AspectJProxyFactory proxyFactory = new AspectJProxyFactory();
proxyFactory.setExposeProxy(true);
return proxyFactory;
}
// 注入AOP切面
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
// 缓存切面
@Aspect
@Component
public class MyAspect {
@Around("execution(* com.example.MyService.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前的逻辑
Object result = joinPoint.proceed();
// 方法执行后的逻辑
return result;
}
}
方式二:使用代理对象调用方法并传递参数
将参数传递给代理对象,然后在代理对象的方法内部调用被代理的方法。
public class MyService {
// 使用代理对象调用方法并传递参数
public void doSomething() {
((MyService) AopContext.currentProxy()).cachedMethod("param");
}
// 需要被代理的方法,添加缓存注解
@Cacheable("myCache")
public void cachedMethod(String param) {
// 方法体
}
}
// 配置AOP与缓存
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableCaching
public class AopConfig {
// 需开启ExposeProxy,以便使用AopContext.currentProxy()
@Bean
public AspectJProxyFactory aspectJProxyFactory() {
AspectJProxyFactory proxyFactory = new AspectJProxyFactory();
proxyFactory.setExposeProxy(true);
return proxyFactory;
}
// 注入AOP切面
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
// 缓存管理器
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}
// 缓存切面
@Aspect
@Component
public class MyAspect {
// 配置缓存切点
@Pointcut("@annotation(org.springframework.cache.annotation.Cacheable)")
public void cacheableMethod() {}
// 缓存环绕通知
@Around("cacheableMethod()")
public Object aroundCacheable(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前的逻辑
Object result = joinPoint.proceed();
// 方法执行后的逻辑
return result;
}
}
总结
使用AopContext.currentProxy()
获取当前代理对象的方式可以解决方法缓存不生效的问题。通过使用代理对象调用方法,或将参数传递给代理对象,然后在代理对象的方法内部调用被代理的方法,可以保证缓存的正常使用。另外,还需要注意配置AOP时开启ExposeProxy,以便使用AopContext.currentProxy()
。
猜您想看
-
如何在Edge浏览器中启用或禁用媒体自动播放?
如何在Micr...
2023年04月15日 -
如何使用iPhone上的健身工具帮助调整健身计划
如何使用iPh...
2023年05月05日 -
python中怎么实现一个Dijkstra算法
Dijkstr...
2023年05月26日 -
什么是MYSQL的开发思路
1. 分析My...
2023年05月22日 -
Flink1.10中Window窗口机制简介
1. Wind...
2023年07月22日 -
宝塔面板网站多语言环境配置方法
1. 环境概述...
2024年05月30日