Springboot Redis整合示范及项目源码
Springboot Redis
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
项目源码免费下载地址:https://download.csdn.net/download/HumorChen99/15834374
-
创建项目
使用idea的spring initializer来创建一个项目,maven依赖如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>springboot_redis_demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_redis_demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
注解方式的
- 项目结构
-
配置application.yml
server: port: 80 spring: redis: #数据库索引 database: 1 host: 192.168.0.198 port: 6379 #密码有就填没有就不要写 password: 123456 jedis: pool: max-active: 8 max-wait: -1ms max-idle: 8 min-idle: 0 timeout: 3s
-
配置类
-
键生成器(你也可以自己指定键,也可指定键生成器去生成)
package com.example.springboot_redis_demo.config; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.lang.reflect.Method; /** * 注解自动缓存所需键生成器 */ @Configuration public class MyKeyGenerator { @Bean(name = "keyGenerator") public KeyGenerator myKeyGenerator(){ return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { String id=o.getClass().getName()+"."+method.getName(); if (objects.length>0){ for(Object obj:objects){ id+="."+obj.toString(); break; } } System.err.println(id); return id; } }; } }
-
Redis配置类
package com.example.springboot_redis_demo.config; import com.example.springboot_redis_demo.serializer.FastJson2JsonRedisSerializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; 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.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * 注解自动缓存所需配置 */ @Configuration public class RedisConfig { @Autowired private FastJson2JsonRedisSerializer fastJson2JsonRedisSerializer; @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); // 配置序列化 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJson2JsonRedisSerializer)); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
-
-
序列化器(查询结果存入redis需要被序列化为文本,采用FastJSON)
package com.example.springboot_redis_demo.serializer; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.SerializerFeature; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import org.springframework.stereotype.Component; import java.nio.charset.Charset; /** * @Author:humorchen * @Date 2020/11/8 13:32 */ @Component public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); static { //由于fastjson有autotype检查,将自己的包前缀加进去防止反序列化失败 ParserConfig.getGlobalInstance().addAccept("com"); } private Class<T> clazz; public FastJson2JsonRedisSerializer() { this((Class<T>) Object.class); } public FastJson2JsonRedisSerializer(Class<T> clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { if (t == null) { return new byte[0]; } return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length <= 0) { return null; } String str = new String(bytes, DEFAULT_CHARSET); return (T) JSON.parseObject(str, clazz); } }
-
测试用的接口Controller
package com.example.springboot_redis_demo.controller; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RestController; /** * 注解自动缓存测试 * key可以通过keyGenerator生成也可以直接指定key */ @RestController public class TestController { private static final String cacheName="TestController"; private static final String keyGenerator="keyGenerator"; /** * 开启缓存(缓存一次后参数相同不再执行方法直接返回缓存内容) */ @Cacheable(cacheNames =cacheName,key ="#id") @GetMapping("/query") public String query(int id){ return "Cacheable"; } /** * 清除缓存(需要键相同,才能清除) * @return */ @CacheEvict(cacheNames =cacheName,key = "#id") @DeleteMapping("/delete") public String delete(int id){ return "CacheEvict"; } /** * 开启缓存(每次缓存且每次执行方法将结果缓存) * 清除这个的缓存也需要会生成同样键的方法上边加@CacheEvict * @return */ @CachePut(cacheNames =cacheName,keyGenerator = keyGenerator) @GetMapping("/query_put") public String query_put(){ return "CachePut"; } }
首先访问localhost/query?id=1,然后可以看到redis里已经有了缓存
然后访问清除缓存的接口,参数还是一样,可以看到缓存被清除了
再访问下用@CachePut注解标注的接口,可以看到缓存好了(这个接口使用的键生成器生成的)
直接指定key的时候呢,用#id来引用请求里的参数id,作为键,而指定keyGenerator的时候,键是通过传入对象,方法,参数过去给键生成器,生成器返回一个键。注解操作的时候是区分键的。
你也可以不指定key或者keyGenerator,只指定cacheNames,那么不管参数是什么结果都是同样的
例如:
@Cacheable(cacheNames = cacheName) @GetMapping("/get") public String get(){ return "get"; }
手动缓存式(RedisTemplate)
不全部列出可用操作,可使用redisTemplate.然后看下有哪些可用的方法
-
配置类
package com.example.springboot_redis_demo.annotation_cache.config; import com.example.springboot_redis_demo.annotation_cache.serializer.FastJson2JsonRedisSerializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * 注解自动缓存所需配置 */ @Configuration public class RedisConfig { @Autowired private FastJson2JsonRedisSerializer fastJson2JsonRedisSerializer; /** * 手动注入使用的RedisTemplate * @param connectionFactory * @return */ @Bean public RedisTemplate<String , Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setValueSerializer(fastJson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
-
序列化器
还是上面那个
package com.example.springboot_redis_demo.annotation_cache.serializer; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.SerializerFeature; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import org.springframework.stereotype.Component; import java.nio.charset.Charset; /** * 基于FastJSON的一个序列化器 * @Author:humorchen * @Date 2020/11/8 13:32 */ @Component public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); static { //由于fastjson有autotype检查,将自己的包前缀加进去防止反序列化失败 ParserConfig.getGlobalInstance().addAccept("com"); } private Class<T> clazz; public FastJson2JsonRedisSerializer() { this((Class<T>) Object.class); } public FastJson2JsonRedisSerializer(Class<T> clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { if (t == null) { return new byte[0]; } return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length <= 0) { return null; } String str = new String(bytes, DEFAULT_CHARSET); return (T) JSON.parseObject(str, clazz); } }
-
测试用的controller NonautomaticController
package com.example.springboot_redis_demo.nonautomatic_cache.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/nonautomatic") public class NonautomaticTestController { @Autowired private RedisTemplate<String,Object> redisTemplate; /** * 读取接口 * @param id * @return */ @GetMapping("/query") public String query(int id){ //先从缓存读取读取不到再去数据库 Object object=redisTemplate.opsForValue().get(id+""); if(object!=null){ return object.toString(); }else{ //查询数据库 } return "not found"; } /** * 写入接口 * @param id * @param value * @return */ @RequestMapping("/set") public String set(int id,String value){ //先写入数据库成功再写缓存 redisTemplate.opsForValue().set(id+"",value); return "set success"; } }
本文来自博客园,作者:HumorChen99,转载请注明原文链接:https://www.cnblogs.com/HumorChen/p/18039654