Spring Boot(11)——使用Spring Cache
使用Spring Cache
Spring提供了Cache抽象,它允许我们声明哪些bean的哪些方法的外部调用需要使用Cache。方法调用使用了Cache后,在调用真实方法前会先从缓存中获取结果,缓存中如果没有则会调用真实方法,这也是基于AOP实现的。关于Spring Cache的介绍不是本文的重点,如有需要可以参考笔者写的http://elim.iteye.com/blog/2123030。
在Spring Boot应用中使用Spring Cache需要在@SpringBootConfiguration
标注的Class上添加@EnableCaching
,这样就启用了Spring Cache。Spring Boot将根据Classpath下提供的Spring Cache实现类选择合适的实现者进行自动配置,支持的实现有基于Ehcache的实现、基于Redis的实现等,详情可参考org.springframework.boot.autoconfigure.cache.CacheConfiguration
的源码。如果没有找到,则会使用基于ConcurrentMap的实现。
下面的代码中就启用了Spring Cache。
@SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.setAddCommandLineProperties(false); app.run(args); } }
然后就可以在bean中使用Spring Cache提供的注解进行缓存的定义了,下面的代码中就定义了getTime()
将使用名称为cacheName1
的缓存。
@Component public class SimpleService { @Cacheable("cacheName1") public long getTime() { return System.currentTimeMillis(); } }
简单的验证缓存生效的单元测试如下。
@SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class CacheTest { @Autowired private SimpleService simpleService; @Test public void testGetTime() throws Exception { long time1 = this.simpleService.getTime(); TimeUnit.MILLISECONDS.sleep(100); long time2 = this.simpleService.getTime(); Assert.assertEquals(time1, time2); } }
使用Ehcache实现
需要使用Spring Cache的Ehcache实现,首先需要在pom.xml中加入如下依赖。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
然后最简单的方式是在Classpath的根路径下放一个ehcache.xml
文件,这样Spring Boot默认就会启用Spring Cache的Ehcache实现了。Ehcache的自动配置由EhCacheCacheConfiguration
定义。如果Ehcache的配置文件不是存放在Classpath根路径,则可以通过spring.cache.ehcache.config
来指定,比如下面的代码指定了在Classpath下的config目录下寻找ehcache.xml文件作为Ehcache的配置文件。
spring.cache.ehcache.config=classpath:/config/ehcache.xml
Spring Cache的自动配置的属性定义类是CacheProperties,参考其API文档或源码可以查看选择的Spring Cache的实现可以指定的详细的配置信息。
SimpleService的getTime()
指定了使用的Cache是名称为cacheName1的Cache。所以在ehcache.xml中需要定义一个名为cacheName1的Cache,配置如下:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" maxBytesLocalHeap="100M"> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <persistence strategy="localTempSwap" /> </defaultCache> <cache name="cacheName1" /> </ehcache>
如果应用中应用了很多不同名称的Cache,如果都把它们在ehcache.xml中定义一次,可能你会觉得太麻烦。可能你想把一些主要的Cache在ehcache.xml中定义,进行充分的自定义配置。然后其它的则能够在使用的时候自动创建,并使用默认的默认的缓存配置,则可以定义自己的EhCacheCacheManager实现bean,实现getMissingCache()
的逻辑为不存在则创建。这样Spring Boot将不再自动创建EhCacheCacheManager bean。下面的代码是一个简单的示例。
@Component public class MyEhCacheCacheManager extends EhCacheCacheManager { @Override protected Cache getMissingCache(String name) { Cache cache = super.getMissingCache(name); if (cache == null) { Ehcache ehcache = super.getCacheManager().addCacheIfAbsent(name); cache = new EhCacheCache(ehcache); } return cache; } }
使用Redis实现
需要使用Redis实现需要在pom.xml中添加spring-boot-starter-data-redis
依赖,这样Spring Boot将自动创建RedisTemplate bean,有了RedisTemplate bean后Spring Boot将自动创建基于Redis实现的Spring Cache的CacheManager,RedisCacheManager。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Spring Boot默认创建的RedisTemplate将使用localhost作为服务地址,端口号是6379,数据库索引为0,可以通过spring.redis.host
指定Redis服务IP,spring.redis.port
指定Redis服务监听端口号,spring.redis.database
指定需要使用的数据库索引号。下面的代码中就指定了使用的是10.10.10.3
这台主机上的Redis,数据库索引号是1。关于Redis的更多配置信息可以参考org.springframework.boot.autoconfigure.data.redis.RedisProperties
的API文档。
spring.redis.host=10.10.10.3 spring.redis.database=1
默认Spring Cache的Redis实现存入Redis中的Key是cacheName::cacheKey
的形式,其中cacheName是当前Spring Cache的name,cacheKey是Spring Cache传递过来的Key。可以通过spring.cache.redis.key-prefix
指定存入Redis中的Key的前缀,当指定了该属性时,生成的Key将是该前缀加上Spring Cache传递过来的Key。比如下面的代码中指定了前缀是test-spring-cache::
,如果Spring Cache传递的Key是key1,则最终存入Redis中的Key将是test-spring-cache::key1
。
spring.cache.redis.key-prefix=test-spring-cache::
可以通过spring.cache.redis.timeToLive
指定Redis缓存的Key的存活时间。下面的代码中就指定了缓存的有效时间是60秒。
spring.cache.redis.timeToLive=60s
关于Spring Cache的Redis实现的更多配置可以参考org.springframework.boot.autoconfigure.cache.CacheProperties.Redis
的API文档。
指定Cache实现
当Classpath下同时存放了多个Spring Cache的实现类,并且同时有多个Spring Cache实现类可以满足启用条件时,Spring Boot将按照一定的顺序进行选择,一旦应用了某个类型的Spring Cache实现后,其它类型的Spring Cache实现将是非启用的,因为这些自动启用的前提都要求当前环境中尚未有Spring Cache的CacheManager类型的bean。自动启用的顺序是按照org.springframework.boot.autoconfigure.cache.CacheType
这个枚举中定义的顺序来的,它的定义如下。
/** * Generic caching using 'Cache' beans from the context. */ GENERIC, /** * JCache (JSR-107) backed caching. */ JCACHE, /** * EhCache backed caching. */ EHCACHE, /** * Hazelcast backed caching. */ HAZELCAST, /** * Infinispan backed caching. */ INFINISPAN, /** * Couchbase backed caching. */ COUCHBASE, /** * Redis backed caching. */ REDIS, /** * Caffeine backed caching. */ CAFFEINE, /** * Simple in-memory caching. */ SIMPLE, /** * No caching. */ NONE
所以一旦Classpath下同时拥有Ehcache和Redis的Spring Cache实现时,将优先使用Ehcache的实现,如果想使用Redis的实现,可以通过spring.cache.type=redis
指定使用Redis的实现。
指定Cache实现仅针对于自动配置生效,如果是自己定义了CacheManager实现,则该配置无效。
CacheManagerCustomizer
CacheManagerCustomizer是用来对CacheManager进行自定义扩展的,其定义如下:
@FunctionalInterface public interface CacheManagerCustomizer<T extends CacheManager> { /** * Customize the cache manager. * @param cacheManager the {@code CacheManager} to customize */ void customize(T cacheManager); }
当需要对某个CacheManager实现进行一些自定义时,可以实现CacheManagerCustomizer接口,指定泛型为需要进行自定义的CacheManager实现类,然后把它定义为一个Spring bean。下面的代码就对Ehcache实现的CacheManager进行了一些自定义,其在EhCacheCacheManager初始化后采用默认的Cache配置创建了一些Cache。
@Component public class EhcacheCacheManagerCustomizer implements CacheManagerCustomizer<EhCacheCacheManager> { @Override public void customize(EhCacheCacheManager cacheManager) { List<String> cacheNames = Arrays.asList("cacheName1", "cacheName2", "cacheName3", "cacheName4", "cacheName5", "cacheName6"); cacheNames.forEach(cacheManager.getCacheManager()::addCacheIfAbsent); } }
关于Spring Cache的自动配置可以参考org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
的源码或API文档。
(注:本文是基于Spring Boot 2.0.3所写)

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
php分页数据最后一页继续追加第一页数据
之前做数据分页遇到这样一个需求,就是数据到最后一页的时候不能中断,继续把第一页的数据追加到后面,无限显示下去。 原文地址:代码汇个人博客 http://www.codehui.net/info/23.html 一般情况我们写数据分页都是如下代码 //分页码 $page = $_REQUEST['page']; //显示条数 $limit = 10; //分页开始条数 $start_limit = ($page - 1) * $limit; //运行sql语句得到的结果 $list = model('table')->limit("$start_limit, $limit")->findAll(); //返回数据 return $list; 比如我们有102条数据,到了11页的时候就会只有2条数据,显然这不是我们要的结果。如果我们想要第11页数据显示的是最后的2条+第1页的前8条,就不能用这种方法了。 //分页码 $page = $_REQUEST['page']; //显示条数 $limit = 10; //数据总条数 $count = model('table')->...
- 下一篇
python3-文本读音器
本篇分享的是使用python3制作一个文本读音器,简单点就是把指定的文本文字转语音说出来;做这么个小工具主要是为了方便自己在平时看一些文章眼累的时候,可通过语音来帮助自己,当然如果你是小说迷,可以扩展成一个小说读音器。 pip install pyttsx3 这里我选择了pyttsx3工具,其实百度的语音接口很不错,不过有些麻烦,我们姑且忽略;先安装python的文字转语音的工具pyttsx3,来简单封装一个文字转语音的方法: import pyttsx3 class ttsx(object): def __init__(self,rate=-10): self.rate = rate def sayText(self,str): self.engine = pyttsx3.init() #语速 rate = self.engine.getProperty('rate') self.engine.setProperty('rate', rate + self.rate) #音量 #volume = self.engine.getProperty('volume') #engine.se...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- 设置Eclipse缩进为4个空格,增强代码规范