SpringBoot2 综合案例(06):集成Redis缓存,和Cache注解模式

Spring Boot 2 基础案例篇

包含:入门、日志管理、定时器、事务、AOP、数据库、缓存、NoSQL、监控、打包。

Spring Boot 2 高级案例篇

包含:整合常用中间件:分库分表、权限管理、Redis 集群、Dubbo、消息队列、定时器、搜索引擎、文件管理、邮件等

Redis 简介

Spring Boot 中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多 NoSQL 数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch。这些案例整理好后,陆续都会上传 Git。

SpringBoot2 版本,支持的组件越来越丰富,对 Redis 的支持不仅仅是扩展了 API,更是替换掉底层 Jedis 的依赖,换成 Lettuce。

本案例需要本地安装一台 Redis 数据库。

Spring2 集成 Redis

核心依赖

    org.springframework.boot    spring-boot-starter-data-redis

配置文件

# 端口server:  port: 8008spring:  application:    # 应用名称    name: node08-boot-redis  # redis 配置  redis:    host: 127.0.0.1    #超时连接    timeout: 1000ms    jedis:      pool:        #最大连接数据库连接数,设 0 为没有限制        max-active: 8        #最大等待连接中的数量,设 0 为没有限制        max-idle: 8        #最大建立连接等待时间。如果超过此时间将接到异常。设为-1 表示无限制。        max-wait: -1ms        #最小等待连接中的数量,设 0 为没有限制        min-idle: 0

这样 Redis 的环境就配置成功了,已经可以直接使用封装好的 API 了。

简单测试案例

import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.concurrent.TimeUnit;@RestControllerpublic class RedisController {    @Resource    private StringRedisTemplate stringRedisTemplate ;    @RequestMapping("/setGet")    public String setGet (){        stringRedisTemplate.opsForValue().set("cicada","smile");        return stringRedisTemplate.opsForValue().get("cicada") ;    }    @Resource    private RedisTemplate redisTemplate ;    /**     * 设置 Key 的有效期 10 秒     */    @RequestMapping("/setKeyTime")    public String setKeyTime (){        redisTemplate.opsForValue().set("timeKey","timeValue",10, TimeUnit.SECONDS);        return "success" ;    }    @RequestMapping("/getTimeKey")    public String getTimeKey (){        // 这里 Key 过期后,返回的是字符串 'null'        return String.valueOf(redisTemplate.opsForValue().get("timeKey")) ;    }}

自定义序列化配置

import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.io.Serializable;/** * Redis 配置 */@Configurationpublic class RedisConfig {    private static final Logger LOGGER = LoggerFactory.getLogger(RedisConfig.class) ;    /**     * 序列化配置     */    @Bean    public RedisTemplate redisTemplate            (LettuceConnectionFactory  redisConnectionFactory) {        LOGGER.info("RedisConfig == >> redisTemplate ");        RedisTemplate template = new RedisTemplate<>();        template.setKeySerializer(new StringRedisSerializer());        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());        template.setConnectionFactory(redisConnectionFactory);        return template;    }}

序列化测试

import com.boot.redis.entity.User;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;@RestControllerpublic class SerializeController {    @Resource    private RedisTemplate redisTemplate ;    @RequestMapping("/setUser")    public String setUser (){        User user = new User() ;        user.setName("cicada");        user.setAge(22);        List list = new ArrayList<>() ;        list.add("小学");        list.add("初中");        list.add("高中");        list.add("大学");        user.setEducation(list);        redisTemplate.opsForValue().set("userInfo",user);        return "success" ;    }    @RequestMapping("/getUser")    public User getUser (){        return (User)redisTemplate.opsForValue().get("userInfo") ;    }}

Cache 缓存简介

从 Spring3 开始定义 Cache 和 CacheManager 接口来统一不同的缓存技术;Cache 接口为缓存的组件规范定义,包含缓存的各种操作集合;Cache 接口下 Spring 提供了各种缓存的实现;如 RedisCache,EhCacheCache ,ConcurrentMapCache 等;

核心 API

1、Cache 缓存接口定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache 等

2、CacheManager缓存管理器,管理各种缓存(cache)组件

3、Cacheable
主要针对方法配置,能够根据方法的请求参数对其进行缓存

Cacheable 执行流程1)方法运行之前,按照 cacheNames 指定的名字先去查询 Cache 缓存组件2)第一次获取缓存如果没有 Cache 组件会自动创建3)Cache 中查找缓存的内容,使用一个 key,默认就是方法的参数4)key 是按照某种策略生成的;默认是使用 keyGenerator 生成的,这里使用自定义配置5)没有查到缓存就调用目标方法;6)将目标方法返回的结果,放进缓存中Cacheable 注解属性cacheNames/value:指定方法返回结果使用的缓存组件的名字,可以指定多个缓存key:缓存数据使用的 keykey/keyGenerator:key 的生成器,可以自定义cacheManager:指定缓存管理器cacheResolver:指定缓存解析器condition:指定符合条件的数据才缓存unless:否定缓存;当 unless 指定的条件为 true,方法的返回值就不会被缓存sync:是否使用异步模式

4、@CacheEvict清除缓存

CacheEvict:缓存清除key:指定要清除的数据allEntries = true:指定清除这个缓存中所有的数据beforeInvocation = false:方法之前执行清除缓存,出现异常不执行beforeInvocation = true:代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除

5、@CachePut
保证方法被调用,又希望结果被缓存。与@Cacheable 区别在于是否每次都调用方法,常用于更新,写入

CachePut:执行方法且缓存方法执行的结果修改了数据库的某个数据,同时更新缓存;执行流程 1)先调用目标方法 2)然后将目标方法的结果缓存起来

6、@EnableCaching开启基于注解的缓存

7、keyGenerator
缓存数据时 key 生成策略

8、@CacheConfig统一配置本类的缓存注解的属性

与 SpringBoot2 整合

核心依赖

    org.springframework.boot    spring-boot-starter-cache

Cache 缓存配置

import org.springframework.cache.interceptor.KeyGenerator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.lang.reflect.Method;@Configurationpublic class CacheConfig {    /**     * 自定义 Cache 的 key 生成器     */    @Bean("oneKeyGenerator")    public KeyGenerator getKeyGenerator (){        return new KeyGenerator() {            @Override            public Object generate(Object obj, Method method, Object... objects) {                return "KeyGenerator:"+method.getName();            }        } ;    }}

启动类注解开启 Cache

@EnableCaching            // 开启 Cache 缓存注解@SpringBootApplicationpublic class CacheApplication {    public static void main(String[] args) {        SpringApplication.run(CacheApplication.class,args) ;    }}

Cache 注解使用代码

1)封装增删改查接口

import com.boot.cache.entity.User;public interface UserService {    // 增、改、查、删    User addUser (User user) ;    User updateUser (Integer id) ;    User selectUser (Integer id) ;    void deleteUser (Integer id);}

2)Cache 注解使用案例

import com.boot.cache.entity.User;import com.boot.cache.service.UserService;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;@Servicepublic class UserServiceImpl implements UserService {    // 使用自定义的 key 生成策略    // 缓存结果 key:addUser::KeyGenerator:addUser    @CachePut(value = "addUser",keyGenerator="oneKeyGenerator")    @Override    public User addUser(User user) {        return user ;    }    // 缓存结果 key:updateUser::2    @CachePut(value = "updateUser",key = "#result.id")    @Override    public User updateUser(Integer id) {        User user = new User() ;        user.setId(id);        user.setName("smile");        return user;    }    // 缓存结果 key: selectUser::3    @Cacheable(cacheNames = "selectUser",key = "#id")    @Override    public User selectUser(Integer id) {        User user = new User() ;        user.setId(id);        user.setName("cicadaSmile");        return user;    }    // 删除指定 key: selectUser::3    @CacheEvict(value = "selectUser",key = "#id",beforeInvocation = true)    @Override    public void deleteUser(Integer id) {    }}

测试代码块

@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = CacheApplication.class)public class CacheTest {    @Resource    private UserService userService ;    // 分别测试:增、改、查、删,四个方法    @Test    public void testAdd (){        User user = new User() ;        user.setId(1);        user.setName("cicada");        userService.addUser(user) ;    }    @Test    public void testUpdate (){        userService.updateUser(2) ;    }    @Test    public void testSelect (){        userService.selectUser(3) ;    }    @Test    public void testDelete (){        userService.deleteUser(3) ;    }}

源代码地址

GitHub 地址:知了一笑https://github.com/cicadasmile/spring-boot-base码云地址:知了一笑https://gitee.com/cicadasmile/spring-boot-base

本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。

阅读全文: http://gitbook.cn/gitchat/activity/5d6fc7cbf1212e15a6c248c5

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

你可能感兴趣的:(SpringBoot2 综合案例(06):集成Redis缓存,和Cache注解模式)