Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案
@Cacheable注解類內(nèi)部調(diào)用失效
如果你只是想使用一個(gè)輕量級(jí)的緩存方案,那么可以嘗試使用Spring cache方案。
那么在使用spring @Cacheable注解的時(shí)候,要注意,如果類A的方法f()被標(biāo)注了@Cacheable注解,那么當(dāng)類A的其他方法,例如:f2(),去直接調(diào)用f()的時(shí)候,@Cacheable是不起作用的,原因是@Cacheable是基于spring aop代理類,f2()屬于內(nèi)部方法,直接調(diào)用f()時(shí),是不走代理的。
舉個(gè)例子:
@Cacheable(key = "#entityType", value = "xxxCache")
? ? public List<String selectByEntityType(intentityType) {
? ? ? ? List<String> result = new ArrayList<>();
? ? ? ? //do something
? ? ? ? return result;
? ? }
public List<String> f2(){
? //Cacheable失效,不會(huì)走緩存的
? selectByEntityType(1);
}可以把selectByEntityType方法抽取到另外的類中,例如:
@Service
public class CacheService{
@Cacheable(key = "#entityType", value = "xxxCache")
? ? public List<String selectByEntityType(intentityType) {
? ? ? ? List<String> result = new ArrayList<>();
? ? ? ? //do something
? ? ? ? return result;
? ? }
}這樣其他類要使用selectByEntityType方法,只能注入CacheService,走代理。
@Cacheable注解緩存方法內(nèi)部調(diào)用
因?yàn)镾pring Cache是基于切面的(基于AOP的動(dòng)態(tài)代理實(shí)現(xiàn)的:即都在方法調(diào)用前后去獲取方法的名稱、參數(shù)、返回值,然后根據(jù)方法名稱、參數(shù)生成緩存的key(自定義的key例外),進(jìn)行緩存),所以內(nèi)部方法調(diào)用不會(huì)調(diào)用切面,導(dǎo)致緩存不生效
方法一
暴露Aop代理到ThreadLocal支持,在類之前加@EnableAspectJAutoProxy(exposeProxy = true)
調(diào)用的時(shí)候使用((XxxService) AopContext.currentProxy()).method()調(diào)用方法
eg:
ApiBaseResponse<ApiPageResponse<RoadCongestIndexData>> apiPageResponseApiBaseResponse = ? ? ? ? ? ? ? ? ((RoadLastPageServiceImpl) AopContext.currentProxy()).queryLastPageCongestIndexData1(request);
方法二
把需要用緩存的方法單獨(dú)寫到一個(gè)類里面,把內(nèi)部調(diào)用變成類間調(diào)用
RoadLastPageServiceImpl selfService = SpringContextUtil.getBean(RoadLastPageServiceImpl.class); ? ? ? ? selfService.queryLastPageCongestIndexData1(request);
方法三
類自我注入,使用@lazy和@Autowired注解實(shí)現(xiàn)自我注入,然后使用時(shí)用注解的實(shí)例代替this調(diào)用方法。
@Lazy @Autowired private RoadLastPageServiceImpl serviceImplCache;
方法四
寫一個(gè)工具類,使用內(nèi)部調(diào)用的時(shí)候,自己實(shí)例化一個(gè)對(duì)象,讓類走AOP
@Component
public class SpringContextUtil implements ApplicationContextAware {
? ? private static ApplicationContext applicationContext;
? ? /**
? ? ?* 實(shí)現(xiàn)ApplicationContextAware接口的回調(diào)方法,設(shè)置上下文環(huán)境
? ? ?*
? ? ?* @param applicationContext
? ? ?*/
? ? @Override
? ? public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
? ? ? ? SpringContextUtil.applicationContext = applicationContext;
? ? }
? ? public static ApplicationContext getApplicationContext() {
? ? ? ? return applicationContext;
? ? }
? ? /**
? ? ?* 獲取對(duì)象
? ? ?*
? ? ?* @param name
? ? ?* @return Object
? ? ?* @throws BeansException
? ? ?*/
? ? public static Object getBean(String name) throws BeansException {
? ? ? ? return applicationContext.getBean(name);
? ? }
? ? /**
? ? ?* 通過(guò)類型獲取對(duì)象
? ? ?*
? ? ?* @param t
? ? ?* ? ? ? ? ? ?對(duì)象類型
? ? ?* @return
? ? ?* @throws BeansException
? ? ?*/
? ? public static <T> T getBean(Class<T> t) throws BeansException {
? ? ? ? return applicationContext.getBean(t);
? ? }
}調(diào)用的時(shí)候這么調(diào)用
RoadLastPageServiceImpl selfService = SpringContextUtil.getBean(RoadLastPageServiceImpl.class); selfService.queryLastPageCongestIndexData1(request);
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何解決redis的NOAUTH Authentication required異常
這篇文章主要介紹了Jedis異常解決:NOAUTH Authentication required,,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值2019-07-07
關(guān)于SpringBoot啟動(dòng)速度慢的原因總結(jié)
這篇文章主要介紹了關(guān)于SpringBoot啟動(dòng)速度慢的原因總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
關(guān)于Spring?Cloud的熔斷器監(jiān)控問(wèn)題
Turbine是一個(gè)聚合Hystrix監(jiān)控?cái)?shù)據(jù)的工具,它可將所有相關(guān)/hystrix.stream端點(diǎn)的數(shù)據(jù)聚合到一個(gè)組合的/turbine.stream中,從而讓集群的監(jiān)控更加方便,接下來(lái)通過(guò)本文給大家介紹Spring?Cloud的熔斷器監(jiān)控,感興趣的朋友一起看看吧2022-01-01
詳解Java LinkedHashMap與HashMap的使用
這篇文章主要通過(guò)幾個(gè)示例為大家詳細(xì)介紹了Java中LinkedHashMap與HashMap的常見(jiàn)使用和概述,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-10-10
java利用冒泡排序?qū)?shù)組進(jìn)行排序
這篇文章主要介紹了java利用冒泡排序?qū)?shù)組進(jìn)行排序的方法,實(shí)例分析了冒泡排序的概念與java實(shí)現(xiàn)方法,以及java操作數(shù)組的相關(guān)技巧,需要的朋友可以參考下2015-05-05
Java通過(guò)調(diào)用FFMPEG獲取視頻時(shí)長(zhǎng)
這篇文章主要為大家詳細(xì)介紹了Java通過(guò)調(diào)用FFMPEG獲取視頻時(shí)長(zhǎng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04

