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()。
猜您想看
-
如何看待nginx入门
1. Ngin...
2023年07月21日 -
如何用Python做个微信朋友圈抽奖九宫格
一、问题描述和...
2023年07月21日 -
SEO是不是技术
SEO是什么?...
2023年05月22日 -
如何在 OpenWrt 中使用 DNSCrypt,并将其配置为路由器级别的解析器?
OpenWrt...
2023年04月17日 -
Linux系统中怎么安装python3.7
1. 检查当前...
2023年07月22日 -
MySQL数据库高性能优化
1.MySQL...
2023年05月25日