出现问题的原因:Spring cache的实现原理是基于AOP的动态代理实现的:即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。this调用不是代理对象的调用, 所以aop失效,注解失效。
解决办法就是,我们获取当前Bean,由它来调用。
SpringContextUtil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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 调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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 ="#id") public User query(Integer id) { return userMapper.selectByPrimaryKey(id); } public User testCacheQuery(Integer id){ TestService service = SpringContextUtil.getBean(TestService.class); return service.query(id); } }
|
参考资料
Springboot Cache @Cacheable 类内部调用时不生效,解决办法