SpringCache学习实践
1. SpringCache学习实践
1.1. 引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
1.2. 启用方式
1.2.1. 添加一种cacheManager的bean
- 若注解了@EnableCaching,则spring可自动发现并配置cacheManager,只要有一种可用于缓存提供的即可,详情见文献[1]。常用的有Ehcache、redis等实现
@Configuration
@EnableCaching
public class CacheConfiguration {
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("models")));
return cacheManager;
}
}
1.3. 使用方式
- 三个主要的注解 Cacheable (最常用的注解,用于标注需要缓存方法)、CacheEvict(用于仅清除缓存)、CachePut(用于仅存放缓存)
- 先定义一个测试POJO: TestModel。 含有name和address两个字符串变量。
class TestModel {
String name;
String address;
// 省略getter和setter
}
1.3.1. Cacheable
@Cacheable(value = "models", key = "#testModel.name", condition = "#testModel.address != '' ")
public TestModel getFromMem(TestModel testModel) throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
testModel.setName(testModel.getName().toUpperCase());
return testModel;
}
- 例子里的注解@Cacheable中存在有以下几个元素
- value (也可使用 cacheNames) : 可看做命名空间,表示存到哪个缓存里了。
- key : 表示命名空间下缓存唯一key,使用Spring Expression Language(简称SpEL,详见参考文献[5])生成。
- condition : 表示在哪种情况下才缓存结果(对应的还有unless,哪种情况不缓存),同样使用SpEL
- 当第一次使用
{name: 'XiaoMing', address: 'ChengDu'}
调用getFromMem时,会等待一秒钟,然后返回
{name: 'XIAOMING', address: 'ChengDu'}
当再次使用name为’XiaoMing’的对象作为参数调用getFromMem时,会立即返回上一个结果,无论参数中的address是什么。
但是如果第一次调用时,address为空字符串,第二次调用仍然需要等待一秒钟,这就是condition的作用。
1.3.2. CacheEvict
@CacheEvict(value = "models", allEntries = true)
@Scheduled(fixedDelay = 10000)
public void deleteFromRedis() {
}
@CacheEvict(value = "models", key = "#name")
public void deleteFromRedis(String name) {
}
例子里的注解 @CacheEvict 中存在有以下几个元素
- value (也可使用 cacheNames) : 同Cacheable注解,可看做命名空间。表示删除哪个命名空间中的缓存
- allEntries: 标记是否删除命名空间下所有缓存,默认为false
- key: 同Cacheable注解,代表需要删除的命名空间下唯一的缓存key。
例子中第一段,与 @Scheduled 注解同时使用,每十秒删除命名空间name下所有的缓存。
第二段,调用此方法后删除命名空间models下, key == 参数 的缓存
同样含有unless与condition
1.3.3. CachePut
@CachePut(value = "models", key = "#name")
public TestModel saveModel(String name, String address) {
return new TestModel(name, address);
}
- 例子里的注解 @CachePut 中存在有以下几个元素
- value: 同上
- key: 同上
- condition(unless): 同上
- 比如可用于后台保存配置时及时刷新缓存。
1.4. Redis作为缓存配置
1.4.1. 引用
- 再加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 然后在配置中添加RedisConnectionFactory用于获取redis链接
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.timeout}")
private int redisTimeout;
@Value("${spring.redis.password}")
private String redisAuth;
@Value("${spring.redis.database}")
private int redisDb;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-wait}")
private int maxWait;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int minIdle;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(maxActive);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMaxWaitMillis(maxWait);
poolConfig.setMinIdle(minIdle);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(true);
JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
.usePooling().poolConfig(poolConfig).and().readTimeout(Duration.ofMillis(redisTimeout)).build();
// 单点redis
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
// 哨兵redis
// RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
// 集群redis
// RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
redisConfig.setHostName(redisHost);
redisConfig.setPassword(RedisPassword.of(redisAuth));
redisConfig.setPort(redisPort);
redisConfig.setDatabase(redisDb);
return new JedisConnectionFactory(redisConfig,clientConfig);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
Jackson2JsonRedisSerializer<Object> serializer = jackson2JsonRedisSerializer();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
return redisTemplate;
}
@Bean
public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
final Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
final ObjectMapper objectMapper = Jackson2ObjectMapperBuilder
.json().build();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
SpringCache学习实践的更多相关文章
- 使用sklearn进行集成学习——实践
系列 <使用sklearn进行集成学习——理论> <使用sklearn进行集成学习——实践> 目录 1 Random Forest和Gradient Tree Boosting ...
- Nagios学习实践系列——基本安装篇
开篇介绍 最近由于工作需要,学习研究了一下Nagios的安装.配置.使用,关于Nagios的介绍,可以参考我上篇随笔Nagios学习实践系列——产品介绍篇 实验环境 操作系统:Red Hat Ente ...
- Nagios学习实践系列——配置研究[监控当前服务器]
其实上篇Nagios学习实践系列——基本安装篇只是安装了Nagios基本组件,虽然能够打开主页,但是如果不配置相关配置文件文件,那么左边菜单很多页面都打不开,相当于只是一个空壳子.接下来,我们来学习研 ...
- 前端学习实践笔记--JavaScript深入【1】
这一年中零零散散看过几本javascript的书,回过头看之前写过的javascript学习笔记,未免有点汗颜,突出“肤浅”二字,然越深入越觉得javascript的博大精深,有种只缘身在此山中的感觉 ...
- Appium学习实践(四)结构优化
随着我们测试脚本中的用例越来越多,我们不可能将所有的用例都放在同一个脚本中,所以我们需要优化我们的结构.将脚本放在一个文件夹中,再通过别的脚本来执行脚本.这样,我们也可以有选择性的执行我们的脚本 先来 ...
- Appium学习实践(三)测试用例脚本以及测试报告输出
之前Appium学习实践(二)Python简单脚本以及元素的属性设置中的脚本,会有一个问题,就是在每个测试用例完成之后都会执行tearDown,然后重新setUp,这样导致脚本的执行效率偏低,而且会有 ...
- Appium学习实践(二)Python简单脚本以及元素的属性设置
1.简单的Python脚本 Appium中的设置与Appium学习实践(一)简易运行Appium中的一致 Launch后,执行脚本 #coding:utf-8 import unittest impo ...
- ReactNative学习实践--Navigator实践
离上次写RN笔记有一段时间了,期间参与了一个新项目,只在最近的空余时间继续学习实践,因此进度比较缓慢,不过这并不代表没有新进展,其实这个小东西离上次发文时已经有了相当大的变化了,其中影响最大的变化就是 ...
- ReactNative学习实践--动画初探之加载动画
学习和实践react已经有一段时间了,在经历了从最初的彷徨到解决痛点时的兴奋,再到不断实践后遭遇问题时的苦闷,确实被这一种新的思维方式和开发模式所折服,react不是万能的,在很多场景下滥用反而会适得 ...
随机推荐
- 泡泡堂BNB[ZJOI2008]
--BZOJ1034 Description 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表队由n名选手组成,比赛的项目是老少咸宜的网络游戏泡泡 ...
- mysql备份最近8天的数据库,老的自动删除方案
服务器上的处理脚本记录: [root@mysql01 test]# crontab -l0 2 * * * /bin/sh /script/sqlbackup.sh >/dev/null 2&g ...
- 安装mq的时候,计算机用户名是中文名的解决办法
在windows下安装rabbitMq ,如果使用用户名是中文的,则会出现启动失败的情况.关于这一点下边给出终极解决方案. 1. 假如你的中文用户名是 XXXXXX,为用户目录建立软链接,软连接名称为 ...
- 安卓学习第一节--环境搭建及Android Studio 安装
1.安装JDK 2.安装AS 安装参考网址 https://www.cnblogs.com/xiadewang/p/7820377.html 下载网址: http://www.android-stud ...
- 根据select出来的数据进行update
update t_tbl_desc set num=b.num from t_tbl_desc a, (select distinct(name) as name,count(name) num fr ...
- EmWin 接触---基础函数
创建对话框,需求两个基本要素:资源表和对话框过程.对话框可以基于阻塞(使用 GUI_ExecDialogBox())或非阻塞(使用 GUI_CreateDialogBox())方式创建.以下为例: G ...
- Maven引入自定义jar包
1.将项目打成jar包 或者下载某个jar包 放在某个目录下(随便吧,桌面也行),这里是放在F:/ jar包为 alipay.jar 2.给jar包取个名字 用原名也行(maven打包默认会 ...
- 受限filterbanks
2.Related works to filterbank learning 虽然DNN-HMM模型的性能比GMM-HMM模型相比,具有很大的优势,但是训练集和测试集之间的失配问题,也使得DNN-HM ...
- CoUninitialize引发的一个错误
程序开始已使用CoUninitialize,后边的函数又再次调用CoUninitialize,判断返回值,导致函数提前退出返回异常.
- php常用字符串方法
chop() 移除字符串右侧的空白字符或其他字符 ltrim() 移除字符串左侧的空白字符或其他字符 rtrim() 移除字符串右侧的空白字符或其他字符 tr ...