Spring@Cacheable注解在类内部调用失效的问题


如图所示,getRecomendGoogs方法里面调用findImgUrlByName方法,在findImgUrlByName方法上使用@Cacheable注解的时候,并没有走缓存。

要解决这个问题,首先我们需要了解spring缓存的原理。spring cache的实现原理跟spring的事务管理类似,都是基于AOP的动态代理实现的:即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。debug可以看到调用的实际上是groupUserBiz的代理类,基于cglib动态代理实现。当调用代理的方法时,代理可以整体控制实际的方法的入参和返回值。比如缓存结果,直接跳过执行实际的方法等。 

找到了原因之后,我们有两种解决方案

第一种:

把findImgUrlByName这个方法单独写到另外的一个类里面去,把类内部调用改成类之间调用

第二种:

使用内部调用的时候,自己实例化一个类对象,让类走AOP,

写一个工具类

@Component
public class SpringContextUtil implements ApplicationContextAware {
    // Spring应用上下文环境
    private static ApplicationContext applicationContext;
 
    /**
     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
     * 
     * @param applicationContext
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextUtil.applicationContext = applicationContext;
    }
 
    /**
     * @return ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
 
    /**
     * 获取对象
     * 
     * @param name
     * @return Object
     * @throws BeansException
     */
    public static Object getBean(String name) throws BeansException {
        return applicationContext.getBean(name);
    }
 
    /**
     * 通过类型获取对象
     * 
     * @param t
     *            对象类型
     * @return
     * @throws BeansException
     */
    public static <T> T getBean(Class<T> t) throws BeansException {
        return applicationContext.getBean(t);
    }
}

在getRecomendGoogs方法调用findImgUrlByName的时候使用

WeCommonService weCommonService = SpringContextUtil.getBean(WeCommonService.class);自己实例化service

 
--------------------- 
作者:总有刁明想害朕 
来源:CSDN 
原文:https://blog.csdn.net/Crystalqy/article/details/83541054 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/zl1zl2zl3/article/details/89815003