Springboot Cache @Cacheable 类内部调用时不生效,解决办法
Springboot Cache @Cacheable 类内部调用时不生效,解决办法| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission |
| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------|
| 17805125| Springboot Cache @Cacheable 类内部调用时不生效,解决办法| 2023-11-02T12:17:00| | BlogPost|
出现问题的原因:Spring cache的实现原理是基于AOP的动态代理实现的:即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。this调用不是代理对象的调用, 所以aop失效,注解失效。
解决办法就是,我们获取当前Bean,由它来调用。
SpringContextUtil
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component;/**
不依赖于Autowired而使用java代码快速获取到spring管理的bean
/
@Component
@Lazy(false)
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil .applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
Service 调用
package com.mark.pay.service;
import com.mark.pay.bean.User;
import com.mark.pay.common.spring.SpringContextUtil;
import com.mark.pay.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
@Service
@CacheConfig(cacheNames = "user",cacheManager = "cacheManager")
public class TestService {
@Autowired
UserMapper userMapper;
@Cacheable( key </span>="#id"<span style="color: #000000;">)
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> User query(Integer id) {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> userMapper.selectByPrimaryKey(id);
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> User testCacheQuery(Integer id){
TestService service </span>= SpringContextUtil.getBean(TestService.<span style="color: #0000ff;">class</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> service.query(id);
}
}
| 648658| | 2023-11-02T12:17:00| false| | 2023-11-02T12:16:38.94| true| 出现问题的原因:Spring cache的实现原理是基于AOP的动态代理实现的:即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。this调用不是代理对象的调用, 所以aop失效,注解失效。 解决办法就是,我们获取当前Bean,| Anonymous|
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现