1、整合redis作为缓存

说明这里springboot版本2.19

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构

1、安装redis,使用docker安装

docker search redis

docker pull redis 下载redis,这里已经下载过了就不演示了

使用docker images 查看容器:

启动redis

docker run -d -p 6379:6379 --name myredis docker.io/redis

将虚拟机的端口和容器的端口绑定并且后台运行

使用客户端连接(host根据自己配置)

配置好进入页面

1.1.1、概念介绍

1.jedis和lettuce介绍

Lettuce 和 Jedis 的定位都是Redis的client

Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接

Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,因为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

springboot2之前redis的连接池为jedis,2.0以后redis的连接池改为了lettuce,lettuce能够支持redis4,需要java8及以上。lettuce是基于netty实现的与redis进行同步和异步的通信,之前看到spring-session-data-redis里的samples已经改为使用LettuceConnectionFactory

所以下面我们看下如何来使用Lettuce来操作Redis

RedisAutoConfiguration 自动配置类

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

可以知道RedisAutoConfiguration完成了对JedisConnectionFactory和LettuceConnectionFactory的自动配置。

同时RedisProperties源码中封装了对redis配置,包括jedis和lettuce

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private final Jedis jedis = new Jedis(); private final Lettuce lettuce = new Lettuce();
}

因此我们在使用时直接通过yml配置即可使用Lettuce来连接Redis

1.1.2、引入starter

使用Lettuce连接Redis,maven项目,引入依赖,注意lettuce连接池的使用需要引入commons-pool2依赖包

 <!--引入redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>

1.1.3、配置redis

application.yml配置

#redis 的配置
# springboot2.x以上如此配置,由于2.x的客户端是lettuce
# 单位要带上
spring:
redis:
host: 192.168.56.101
port: 6379
database: 0 lettuce:
pool:
max-active: 8
min-idle: 0
max-idle: 8
max-wait: 10000ms
shutdown-timeout: 100ms

1.1.4、测试redis是否成功

原理:RedisAutoConfiguration中有两个操作类

stringRedisTemplate; //操作k,v都是字符串

redisTemplate; //操作k,v 都是对象

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration { @Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
} @Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
} }

Redis:常见的五大数据类型:String、List(列表)、Set(集合) Hash(散列) 、ZSet(有序集合) stringRedisTemplate.opsForValue() [String]

stringRedisTemplate.opsForList() [List]

stringRedisTemplate.opsForSet() [Set]

stringRedisTemplate.opsForHash() [Hash]

stringRedisTemplate.opsForZSet() [ZSet]

redis中测试保存对象(以json格式)

    @Test
public void testRedis02(){
Employee emp = employeeMapper.getEmpById(1);
//默认如果保存对象,使用jdk序列化机制,序列化的数据保存在redis中
//redisTemplate.opsForValue().set("emp-01",emp);
/**将数据以json形式保存
* 1、自己转为json
* 2、redisTemplate默认的序列化规则,可以改变序列化规则,自定义配置类
*/
EmployeeRedisTemplate.opsForValue().set("emp-01",emp); }

自定义redis配置类

@Configuration
public class MyRedisConfig { @Bean
public RedisTemplate<Object, Employee> EmployeeRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Employee> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
template.setDefaultSerializer(valueSerializer());
return template; }

结果

1.1.5、测试redis缓存

原理:CacheManager===Cache缓存组件来实际给缓存中存取数据, *

这时候org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration失效,用org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration代替,原因是:

提前判断是否有CacheManager.class判断成功,有了redis的RedisCacheManager

@Configuration
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration { @Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
}

@ConditionalOnMissingBean(CacheManager.class) redis顺序在前,因此加载RedisCacheManager

1、引入redis的start,容器中保存的是RedisCacheManager

2、RedisCacheManager帮我们创建RedisCache来作为缓存组件,RedisCache通过redis缓存数据

3、默认保存数据k-v都是Object类型的,默认利用序列化

怎么以json保存?

RedisCacheConfiguration

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.bud());
}

​ 1、引入了redis的starter,CacheManager变为RedisCacheManager *

​ 2、默认创建的RedisCacheManager操作redis缓存数据是通过cacheDefaults()

RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory)      .cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));

​ 3、调用 this.defaultCacheConfiguration = defaultCacheConfiguration;

public static class RedisCacheManagerBuilder {
private RedisCacheConfiguration defaultCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); public RedisCacheManagerBuilder cacheDefaults(RedisCacheConfiguration defaultCacheConfiguration) { Assert.notNull(defaultCacheConfiguration, "DefaultCacheConfiguration must not be null!"); this.defaultCacheConfiguration = defaultCacheConfiguration; return this;
}

4、再调用defaultCacheConfig()

RedisCacheConfiguration

注意RedisCacheConfiguration是spring-data-redis下的配置包,区别redis的自动配置包

public static RedisCacheConfiguration defaultCacheConfig() {
return defaultCacheConfig(null);
}

可以查看defaultCacheConfig方法查看默认的序列化机制

public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader classLoader) {

		DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();

		registerDefaultConverters(conversionService);

		return new RedisCacheConfiguration(Duration.ZERO, true, true, CacheKeyPrefix.simple(),
SerializationPair.fromSerializer(RedisSerializer.string()),
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
}
SerializationPair.fromSerializer(RedisSerializer.string()),
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);

默认使用jdk序列化机制

static RedisSerializer<Object> java(@Nullable ClassLoader classLoader) {
return new JdkSerializationRedisSerializer(classLoader);
}

1.1.6自定义缓存管理器

在redis配置类中

@Configuration
public class MyRedisConfig {
// key键序列化方式
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
} // value值序列化方式
private GenericJackson2JsonRedisSerializer valueSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
/*
* 配置缓存管理器
* @Primary 具有多个缓存管理器,必须得指定一个默认的缓存管理器,springboot1.5.9要制定
* */
//@Primary
@Bean
public RedisCacheManager myRedisCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
// 设置key的序列化方式
.entryTtl(Duration.ofSeconds(600000)) // 60s缓存失效
// 设置key的序列化方式
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
// 设置value的序列化方式
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
// 不缓存null值
.disableCachingNullValues();
RedisCacheManager redisCacheManager= RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config)
.transactionAware()
.build();
System.out.println("自定义RedisCacheManager加载完成");
return redisCacheManager; }

配置完成

测试:

service

@Service
public class DeptService {
@Autowired
DeparmentMapper deparmentMapper; //@Qualifier("myRedisCacheManager")
@Autowired
RedisCacheManager redisCacheManager;
// 可以从缓存中获取数据,可以对缓存进行操作 public Department getDeptById(Integer id){
Department department =deparmentMapper.getDeptByID(id);
Cache dept = redisCacheManager.getCache("dept");
dept.put("dept:dept1",department);
return department; }

controller

@RestController
public class DeptController {
@Autowired
DeptService deptService; @GetMapping("/dept/{id}")
public Department getDeptById(@PathVariable("id") Integer id){
return deptService.getDeptById(id);
} }

结果:

1.2_springboot2.x中redis缓存&原理介绍的更多相关文章

  1. 1.1_springboot2.x与缓存原理介绍&使用缓存

    一.springboot与缓存介绍&使用缓存 1.JSR107 JAVA Cahing定义了5个核心接口,分别是CachingProvider.CacheManager.Cache.Entry ...

  2. 写给后端程序员的HTTP缓存原理介绍

    There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Ka ...

  3. redis—Spring中redis缓存的简单使用

    这里使用的是 Spring-4.3 , redis-2.8 的版本   1.添加maven依赖 <dependency> <groupId>redis.clients</ ...

  4. 写给后端程序员的HTTP缓存原理介绍--怎样决定一个资源的Cache-Control策略呢

    通过Internet获取资源既缓慢,成本又高.为此,Http协议里包含了控制缓存的部分,以使Http客户端可以缓存和重用以前获 取的资源,从而优化性能,提升体验.虽然Http中关于缓存控制的部分,随着 ...

  5. JAVA记录-redis缓存机制介绍(一)

    1.redis介绍 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Re ...

  6. redis主从原理介绍(三)

    博客参考:散尽浮华的Redis主从复制下的工作原理梳理 此作者写的非常好,此处只做挪用,方便自己查看. Redis主从复制的配置十分简单,它可以使从服务器是主服务器的完全拷贝.需要清除Redis主从复 ...

  7. JAVA记录-redis缓存机制介绍(三)

    Redis 事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...

  8. SpringBoot中redis的使用介绍

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...

  9. Linux中Postfix邮件原理介绍(一)

    邮件相关协议 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议, 工作在TCP的25端口.它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式 ...

随机推荐

  1. Java中的接口是怎么实现的

    接口 使用关键字interface来定义一个接口,和类的定义方法很相似分为接口声明和接口体. interface  Printable { final int MAX = 100; void add( ...

  2. net core静态文件 访问除默认目录文件配置

    在我们项目的实际应用中,不光是需要访问默认静态文件夹 wwwroot ,还有可能要要去访问除默认目录以外的文件夹,接下来我们进行配置 1.在根目录创建一个文件夹,继续创建它的子文件夹Images,在I ...

  3. C/C++各个周期的学习

    C/C++ 程序的生命周期 编写时: 要点:业务,数据结构,控制解耦:健壮:易修改:清晰简单无歧义:易重用:低耦合高内聚:易链接:速度快(时间复杂度,空间复杂度,cache友好): 书籍:<c+ ...

  4. 起手一个mpvue项目准备

    1,环境配置(http://mpvue.com/mpvue/quickstart.html) //全局安装vue-cli3脚手架 npm install -g @vue/cli @vue/cli-in ...

  5. PHP ftp_raw() 函数

    定义和用法 ftp_raw() 函数向 FTP 服务器发送一个 raw 命令. 语法 ftp_raw(ftp_connection,command) 参数 描述 ftp_connection 必需.规 ...

  6. Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法

    首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject  NewObject(jclass clazz  , jmethodI ...

  7. flume注意的事项

    bin/flume-ng agent --conf conf/ --name a3 --conf-file conf/flume-dir.conf & 在使用Spooling Director ...

  8. BZOJ 3779: 重组病毒(线段树+lct+树剖)

    题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...

  9. (转)The connection to adb is down, and a severe error has occured. .

    转:http://blog.csdn.net/yu413854285/article/details/7559333 启动android模拟器时.有时会报The connection to adb i ...

  10. Java习题10.25

    Java习题10.25 1. 实际上这道题考查的是两同两小一大原则: 方法名相同,参数类型相同 子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类 ...