您当前的位置: 首页 > 

zmc@

暂无认证

  • 0浏览

    0关注

    142博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

@Cacheable注解不生效原因

zmc@ 发布时间:2019-01-02 10:46:31 ,浏览量:0

@Cacheable注解中:

一个方法A调同一个类里的另一个有缓存注解的方法B,这样是不走缓存的。

例如在同一个service里面两个方法的调用,缓存是不生效的;

 

解决方案:

1.不使用注解的方式,直接取 Ehcache 的 CacheManger 对象,把需要缓存的数据放到里面,类似于使用 Map,缓存的逻辑自己控制;或者可以使用redis的缓存方式去添加缓存;

2.把方法A和方法B放到两个不同的类里面,例如:如果两个方法都在同一个service接口里,把方法B放到另一个service里面,这样在A方法里调B方法,就可以使用B方法的缓存。

 

原理:

	
    // get 方法调用了 stockGive 方法,stockGive 方法使用了缓存
    // 但是每次执行get 方法的时候,缓存都没有生成,也就是缓存没有被创建
    public void get(){
        stockGive(0L);
    }

    @Override
    @Cacheable(value = CacheConfig.COMMON, key = "'stock/give'+#memberId")
    public List stockGive(Long memberId) {
        // do something
    }

为什么缓存没有被正常创建?? 因为@Cacheable 是使用AOP 代理实现的 ,通过创建内部类来代理缓存方法,这样就会导致一个问题,类内部的方法调用类内部的缓存方法不会走代理,不会走代理,就不能正常创建缓存,所以每次都需要去调用数据库。

@Cacheable 的一些注意点 1、因为@Cacheable 由AOP 实现,所以,如果该方法被其它注解切入,当缓存命中的时候,则其它注解不能正常切入并执行,@Before 也不行,当缓存没有命中的时候,其它注解可以正常工作

2、@Cacheable 方法不能进行内部调用,否则缓存无法创建  

 

------------------------------------------------------------------

 

@Cacheable标注的方法,如果其所在的类实现了某一个接口,那么该方法也必须出现在接口里面,否则cache无效。 具体的原因是, Spring把实现类装载成为Bean的时候,会用代理包装一下,所以从Spring Bean的角度看,只有接口里面的方法是可见的,其它的都隐藏了,自然课看不到实现类里面的非接口方法,@Cacheable不起作用。

解决办法:把待cache的方法移到接口里面。

另外衍生两个小问题: 1. @Cacheable放接口里面可以吗?答案是:不行。 2. 如果某一个Bean并没有实现任何接口,@Cacheable标注的方法有什么要求?    答案是public即可。这种Bean也被Spring产生了代理, 看得到的只有public方法。

本质是Spring代理的问题,很多的基础设施可能都会遇到类似的问题。比如安全,事务,日志等等。  

 

 

 

关注
打赏
1643271353
查看更多评论
立即登录/注册

微信扫码登录

0.0368s