现象

Spring @Cacheable注解类内部调用失效 如果类A的方法F1()标注了@Cacheable注解,类A的其他方法,例如:F2()调用F1()时,@Cacheable是失效的

原因

注解@Cacheable是基于spring Aop代理类(即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存),F2()属于内部方法,直接调用F1()时,是不走代理的,导致缓存失效。

例子

@Service
public class TestService {
    @Cacheable(key = "#key", value = "defaultCacheManager")
    public String selectName(String key) {
        //一些业务查询,如查询sql
        return result;
    }

    public String process() {
        //Cacheable失效,不会走缓存的
        return selectName("张三");
    }
}

解决方案

方案一

把需要用缓存的方法单独写到一个类里面,把内部调用变成类间调用

方案二

类自我注入,使用@lazy和@Autowired注解实现自我注入,然后使用时用注解的实例代替this调用方法。

@Service
public class TestService {
    @Lazy
    @Autowired
    private TestService testService;

    @Cacheable(key = "#key", value = "defaultCacheManager")
    public String selectName(String key) {
        //一些业务查询,如查询sql
        return result;
    }

    public String process() {
        return testService.selectName("张三");
    }
}

方案三

暴露Aop代理到ThreadLocal支持,在类之前加@EnableAspectJAutoProxy(exposeProxy = true) 调用的时候使用((XxxService) AopContext.currentProxy()).method()调用方法

@EnableAspectJAutoProxy(exposeProxy = true)
@Service
public class TestService {
    
    @Cacheable(key = "#key", value = "defaultCacheManager")
    public String selectName(String key) {
        //一些业务查询,如查询sql
        return result;
    }

    public String process() {
        return ((TestService) AopContext.currentProxy()).selectName("张三");
    }
}
文章作者: tudan
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 土蛋
喜欢就支持一下吧