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()。
猜您想看
-
C++ 中bind函数如何使用
1、bind函...
2023年05月22日 -
如何加入Hystrix熔断器
1. 什么是H...
2023年07月22日 -
Linux如何整合Apache和SVN
整合Apach...
2023年07月21日 -
如何在微信中开启语音输入功能?
如何在微信中...
2023年04月15日 -
如何在 LEDE 路由器上使用 NFS?
如何在 LED...
2023年04月17日 -
WebMagic爬虫知识点有哪些
一、WebMa...
2023年05月23日