• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Spring Boot缓存源码的理解

springboot 搞代码 4年前 (2022-01-09) 30次浏览 已收录 0个评论

本篇文章给大家带来的内容是关于Spring Boot缓存源码的理解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

项目里面要增加一个应用缓存,原本想着要怎么怎么来整合ehcache和springboot,做好准备配置这个配置那个,结果只需要做三件事:

pom依赖

写好一个ehcache的配置文件

在boot的application上加上注解@EnableCaching.
这就完事了,是不是很魔幻。

pom依赖

<dependency>            <groupId>net.sf.ehcache</groupId>            <artifactId>ehcache</artifactId>            <version>2.10.5</version></dependency>

配置文件

<?xml version="1.0" encoding="UTF-8"?><ehcache>    <!-- 设定缓存的默认数据过期策略 -->    <defaultCache            maxElementsInMemory="500"            maxElementsOnDisk="2000"            eternal="false"            overflowToDisk="true"            timeToIdleSeconds="90"            timeToLiveSeconds="300"            diskPersistent="false"            diskExpiryThreadIntervalSeconds="300"/></ehcache>

应用上加上EnableCaching注解

@SpringBootApplication@EnableCachingpublic class EhCacheApplication {    public static void main(String[] args) {        SpringApplication.run(EhCacheApplication.class, args);    }}

然后就可以在代码里面使用cache注解了,像这样。

@CachePut(value = "fish-ehcache", key = "#person.id")    public Person save(Person person) {        System.out.println("为id、key为:" + person.getId() + "数据做了缓存");        return person;    }    @CacheEvict(value = "fish-ehcache")    public void remove(Long id) {        System.out.println("删除了id、key为" + id + "的数据缓存");    }    @Cacheable(value = "fish-ehcache", key = "#person.id")    public Person findOne(Person person) {        findCount.incrementAndGet();        System.out.println("为id、key为:" + person.getId() + "数据做了缓存");        return person;    }

很方便对不对。下面,我们就来挖一挖,看看spring是怎么来做到的。主要分成两部分,一是启动的时候做了什么,二是运行的时候做了什么,三是和第三方缓存组件的适配

启动的时候做了什么、

这个得从@EnableCaching标签开始,在使用缓存功能时,在springboot的Application启动类上需要添加注解@EnableCaching,这个标签引入了

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Import({CachingConfigurationSelector.class})public @interface EnableCaching {    boolean proxyTargetClass() default false;  <p>本文来源gao!%daima.com搞$代*!码$网9</p>  AdviceMode mode() default AdviceMode.PROXY;    int order() default 2147483647;}

引入了CachingConfigurationSelector类,这个类便开启了缓存功能的配置。这个类添加了AutoProxyRegistrar.java,ProxyCachingConfiguration.java两个类。

  • AutoProxyRegistrar : 实现了ImportBeanDefinitionRegistrar接口。这里看不懂,还需要继续学习。

  • ProxyCachingConfiguration : 是一个配置类,生成了BeanFactoryCacheOperationSourceAdvisor,CacheOperationSource,和CacheInterceptor这三个bean。

CacheOperationSource封装了cache方法签名注解的解析工作,形成CacheOperation的集合。CacheInterceptor使用该集合过滤执行缓存处理。解析缓存注解的类是SpringCacheAnnotationParser,其主要方法如下

/**由CacheOperationSourcePointcut作为注解切面,会解析SpringCacheAnnotationParser.java扫描方法签名,解析被缓存注解修饰的方法,将生成一个CacheOperation的子类并将其保存到一个数组中去**/protected Collection<CacheOperation> parseCacheAnnotations(SpringCacheAnnotationParser.DefaultCacheConfig cachingConfig, AnnotatedElement ae) {        Collection<CacheOperation> ops = null;        //找@cacheable注解方法        Collection<Cacheable> cacheables = AnnotatedElementUtils.getAllMergedAnnotations(ae, Cacheable.class);        if (!cacheables.isEmpty()) {            ops = this.lazyInit(ops);            Iterator var5 = cacheables.iterator();            while(var5.hasNext()) {                Cacheable cacheable = (Cacheable)var5.next();                ops.add(this.parseCacheableAnnotation(ae, cachingConfig, cacheable));            }        }        //找@cacheEvict注解的方法        Collection<CacheEvict> evicts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class);        if (!evicts.isEmpty()) {            ops = this.lazyInit(ops);            Iterator var12 = evicts.iterator();            while(var12.hasNext()) {                CacheEvict evict = (CacheEvict)var12.next();                ops.add(this.parseEvictAnnotation(ae, cachingConfig, evict));            }        }        //找@cachePut注解的方法        Collection<CachePut> puts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class);        if (!puts.isEmpty()) {            ops = this.lazyInit(ops);            Iterator var14 = puts.iterator();            while(var14.hasNext()) {                CachePut put = (CachePut)var14.next();                ops.add(this.parsePutAnnotation(ae, cachingConfig, put));            }        }        Collection<Caching> cachings = AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class);        if (!cachings.isEmpty()) {            ops = this.lazyInit(ops);            Iterator var16 = cachings.iterator();            while(var16.hasNext()) {                Caching caching = (Caching)var16.next();                Collection<CacheOperation> cachingOps = this.parseCachingAnnotation(ae, cachingConfig, caching);                if (cachingOps != null) {                    ops.addAll(cachingOps);                }            }        }        return ops;}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring Boot缓存源码的理解

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址