源码追踪Cacheable注解的执行过程

Cacheable注解是典型的Spring AOP实现,在Spring里,aop可以简单的理解为代理(AspectJ除外),我们声明了@Cacheable的方法的类,都会被代理,在代理中,实现缓存的查询与设置操作。

众所周知,使用CgLib进行AOP动态代理是通过拦截器中的invoke方法执行的。

在这里找到了缓存方面的代理配置。

在配置中看到声明了一个CacheInterceptor的拦截器。

 他实现了MethodInterceptor接口并重写其invoke方法。其中excute的主要逻辑在CacheAspectSupport中。

在CacheAspectSupport中可以找到方法:

而在setCacheManager方法中,了解到将该cacheManager使用SimpleCacheResolver的构造方法赋值给了SimpleCacheResolver。

在执行Aspect的invoke方法追踪下来,发现寻找Cache使用的是该语句:

这里使用了上一个步骤中的cacheResolver进行操作。
接着向下寻找实际调用逻辑,在AbstractCacheResolver中终于发现了实际操作是使用CacheManager中的getCache方法。而AbstractCacheResolver是刚才SimpleCacheResolver的父类,由此我们明白,spring创建了CacheManager的对象并且在resolve中使用getCache(cacheName)。

找到Cahce后,程序返回Cache.get(Object key, Callable valueLoader)方法的返回值。

并且通过wrapCacheValue方法进行了一个非null值的包装。

private Object wrapCacheValue(Method method, Object cacheValue) {
    return method.getReturnType() != javaUtilOptionalClass || cacheValue != null && cacheValue.getClass() == javaUtilOptionalClass ? cacheValue : CacheAspectSupport.OptionalUnwrapper.wrap(cacheValue);
}

结论:

由以上源码可以知道spring的cache是由一个CacheManager的实现对象中的方法:


 * Return the cache associated with the given name.
 * @param name the cache identifier (must not be {@code null})
 * @return the associated cache, or {@code null} if none found
 */
Cache getCache(String name);

找到Cache。并由Cache中的

<T> T get(Object key, Callable<T> valueLoader);

方法执行后续查找,写入等逻辑。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值