文档章节

springboot 整合redis

暗中观察
 暗中观察
发布于 2018/05/19 23:26
字数 904
阅读 393
收藏 0

1,准备

①,一个linux虚拟机,安装好docker,再安装redis镜像,然后启动redis容器

#下载redis镜像
docker pull registry.docker-cn.com/library/redis

#-d 后台运行 -p 暴露端口 --name 起名 最后带上镜像名即可
docker run -d -p 6379:6379 --name myredis bfcb1f6df2db

#启动redis 容器
docker start myredis

②,身为程序员linux不可不玩,而docker就是一个强有力的工具

③,springboot版本2.0.2.RELEASE

④,pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
 <dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

2,redis配置

import java.net.UnknownHostException;
import java.time.Duration;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@EnableCaching
@Configuration
public class CacheConfig {

	@Bean
	public RedisCacheConfiguration redisCacheConfiguration() {
		RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
				Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		// 将类型序列化到属性json字符串中
		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		jackson2JsonRedisSerializer.setObjectMapper(om);
		configuration = configuration
				.serializeValuesWith(
						RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
				.entryTtl(Duration.ofDays(30));
		return configuration;
	}

	@Bean
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
				Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		// 将类型序列化到属性json字符串中
		jackson2JsonRedisSerializer.setObjectMapper(om);
		
		template.setKeySerializer(jackson2JsonRedisSerializer);
		template.setValueSerializer(jackson2JsonRedisSerializer);
		return template;
	}
}

3,application.properties 配置

spring.redis.host=192.168.43.28
spring.redis.port=6379

①,注意只要配置了如上信息,

springboot的默认缓存就会从SimpleCacheConfiguration 切换成RedisCacheConfiguration
②,原理如下

@Configuration
//主要是这里,当没有CacheManager 时生效
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class SimpleCacheConfiguration {

③,springboot缓存的加载循序如下

//CacheAutoConfiguration 的配置如下
static class CacheConfigurationImportSelector implements ImportSelector {

		@Override
		public String[] selectImports(AnnotationMetadata importingClassMetadata) {
			CacheType[] types = CacheType.values();
			String[] imports = new String[types.length];
			for (int i = 0; i < types.length; i++) {
				imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
			}
			return imports;
		}

	}

因为redis在simple的前面,一旦RedisCacheConfiguration 生效就会配置RedisCacheManager,然后simple就不注入ioc容器了

4,RedisCacheConfiguration 生效

//使用RedisCacheManager 用于创建cache	
@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());
	}
//RedisCacheManager 创建cache的方法	
protected RedisCache createRedisCache(String name, @Nullable RedisCacheConfiguration cacheConfig) {
		return new RedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig);
	}

5,RedisCache 创建缓存的流程

//①,根据一定的策略生成缓存的key
protected String createCacheKey(Object key) {

		String convertedKey = convertKey(key);

		if (!cacheConfig.usePrefix()) {
			return convertedKey;
		}

		return prefixCacheKey(convertedKey);
	}

//②,先尝试获取缓存
	public byte[] get(String name, byte[] key) {

		Assert.notNull(name, "Name must not be null!");
		Assert.notNull(key, "Key must not be null!");

		return execute(name, connection -> connection.get(key));
	}
//③,获取不到就执行目标方法,并将返回结果放入缓存
public void put(Object key, @Nullable Object value) {

		Object cacheValue = preProcessCacheValue(value);

		if (!isAllowNullValues() && cacheValue == null) {

			throw new IllegalArgumentException(String.format(
					"Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisCacheConfiguration.",
					name));
		}

		cacheWriter.put(name, createAndConvertCacheKey(key), serializeCacheValue(cacheValue), cacheConfig.getTtl());
	}

6,获取缓存的过程

//①,根据一定的策略生成缓存的key
protected String createCacheKey(Object key) {

		String convertedKey = convertKey(key);

		if (!cacheConfig.usePrefix()) {
			return convertedKey;
		}

		return prefixCacheKey(convertedKey);
	}
//②,尝试根据可以获取对应的缓存
	@Override
	public byte[] get(String name, byte[] key) {

		Assert.notNull(name, "Name must not be null!");
		Assert.notNull(key, "Key must not be null!");

		return execute(name, connection -> connection.get(key));
	}
//③,获取成功则不执行目标方法,直接将缓存返回

7,缓存在redis的样子

①,注意,缓存的数据要带有缓存的类型,否则redis缓存反序列化成对应pojo会失败,只要按上面的CacheConfig配置好RedisCacheConfiguration 即可

8,controller测试

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class RedisController {

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;
	
	@RequestMapping("put")
	@ResponseBody
	public String put(String key) {
		ValueOperations<Object, Object> opsForValue = redisTemplate.opsForValue();
		Object val = opsForValue.get(key);
		if(val==null) {
			String value="小纯"+key;
			opsForValue.set(key, value);
			return "key:"+key+",val"+value +",加入缓存";
		}		
		return "key:"+key+",val"+val +",已在缓存中存在";
	}
}

 

© 著作权归作者所有

暗中观察

暗中观察

粉丝 7
博文 131
码字总数 46797
作品 0
惠州
私信 提问
SpringBoot 学习二:操作数据库

本文将从以下几个方面介绍: 前言 配置数据源 SpringBoot 整合 Mybatis SpringBoot 整合 JdbcTemplate SpringBoot 整合 Redis 前言 在上篇文章 SpringBoot 学习一 中已经学习了 SpringBoot的...

tsmyk0715
2018/09/26
636
0
SpringBoot整合Redis、ApacheSolr和SpringSession

一、简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐。它提供了各种starter简化很多繁琐的配置。SpringBoot整合Druid、Mybatis已经司空见惯,在这里就不详细介绍了。今天...

小忽悠
2018/07/19
0
0
Spring Boot学习笔记

多模块开发 [SpringBoot学习]-IDEA创建Gradle多Module结构的SpringBoot项目 RabbitMQ RabbitMQ 安装 linux安装RabbitMQ详细教程 Ubuntu 16.04 RabbitMq 安装与运行(安装篇) ubantu安装...

OSC_fly
2018/07/26
0
0
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
2018/04/19
0
0
SpringBoot整合Drools7.0

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013115157/article/details/88413946 SpringBoot相信大家都很熟悉了,这里小编就再进行讲述了,由于现在用S...

MorganLai
03/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

会用python把linux命令写一遍的人,进大厂有多容易?

看过这篇《2000字谏言,给那些想学Python的人,建议收藏后细看!》的读者应该都对一个命令有点印象吧?没错,就是 linux 中经常会用到的 ls 命令。 文章中我就提到如何提升自己的 python 能力...

上海小胖
14分钟前
1
0
HashMap的特性

一、hashmap数据结构:哈希表结构:数组+链表 hashmap调用默认构造方法会产生一个默认底层是长度为16的Entry数组,首先调用key的hasCode()方法来得到一个整数, int hash = hash(key.hashCode...

GGbird
14分钟前
10
0
第五章 spring-connet之Imports注解来龙去脉

前言 imports是一个在spring体系里非常重要的注解,基本每个Enable开头的注解必然有一个import注解。接下来我们深入研究下import的作用。看小节的同学建议先取看PostProcessorRegistrationDe...

鸟菜啊
18分钟前
2
0
CentOS部署Harbor镜像仓库

关于Harbor Harbor是用于存储和分发Docker镜像的镜像仓库服务,相比Docker Registry,Harbor在安全、标识、管理等方面做了增强,更适合企业使用; 官方网站:https://goharbor.io/ 官方开源:...

程序员欣宸
22分钟前
3
0
JavaScript调试必会的8个console方法

每个JavaScript开发者都用过console.log()来调试程序,但实际上Console对象还提供了很多其他方法可以提高调试效率。本文将介绍8个有趣的Console方法,即使JavaScript老手也不一定知道! 1、c...

汇智网教程
44分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部