Spring Boot 整合 Spring Cache + Redis

Posted 晨M风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 整合 Spring Cache + Redis相关的知识,希望对你有一定的参考价值。

1.安装redis

  a.由于官方是没有Windows版的,所以我们需要下载微软开发的redis,网址:https://github.com/MicrosoftArchive/redis/releases

  b.解压后,在redis根目录打开cmd界面,输入:redis-server.exe redis.windows.conf,启动redis(关闭cmd窗口即停止)

 

 

2.使用

  a.创建SpringBoot工程,选择maven依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        .....

    </dependencies>

 

 

  b.配置 application.yml 配置文件

server:
  port: 8080
spring:
  # redis相关配置
  redis:
    database: 0
    host: localhost
    port: 6379
    password:
    jedis:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 5
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接超时时间(毫秒)默认是2000ms
    timeout: 2000ms
  # thymeleaf热更新
  thymeleaf:
    cache: false

 

 

  c.创建RedisConfig配置类

@Configuration
@EnableCaching  //开启缓存
public class RedisConfig {

    /**
     * 缓存管理器
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 设置缓存的默认过期时间,也是使用Duration设置
        config = config.entryTtl(Duration.ofMinutes(30))
                // 设置 key为string序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                // 设置value为json序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
                // 不缓存空值
                .disableCachingNullValues();

        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("userCache", config.entryTtl(Duration.ofSeconds(60)));

        // 使用自定义的缓存配置初始化一个cacheManager
        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
                //默认配置
                .cacheDefaults(config)
                // 特殊配置(一定要先调用该方法设置初始化的缓存名,再初始化相关的配置)
                .initialCacheNames(configMap.keySet())
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    /**
     * Redis模板类redisTemplate
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // key采用String的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer());
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer());
        return template;
    }

    /**
     * json序列化
     * @return
     */
    private RedisSerializer<Object> jackson2JsonRedisSerializer() {
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        return serializer;
    }

}

 

 

  d.创建entity实体类

public class User implements Serializable {

    private int id;
    private String userName;
    private String userPwd;

    public User(){}

    public User(int id, String userName, String userPwd) {
        this.id = id;
        this.userName = userName;
        this.userPwd = userPwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

}

 

 

  e.创建Service

@Service
public class UserService {

    //查询:先查缓存是是否有,有则直接取缓存中数据,没有则运行方法中的代码并缓存
    @Cacheable(value = "userCache", key = "‘user:‘ + #userId")
    public User getUser(int userId) {
        System.out.println("执行此方法,说明没有缓存");
        return new User(userId, "用户名(get)_" + userId, "密码_" + userId);
    }

    //添加:运行方法中的代码并缓存
    @CachePut(value = "userCache", key = "‘user:‘ + #user.id")
    public User addUser(User user){
        int userId = user.getId();
        System.out.println("添加缓存");
        return new User(userId, "用户名(add)_" + userId, "密码_" + userId);
    }

    //删除:删除缓存
    @CacheEvict(value = "userCache", key = "‘user:‘ + #userId")
    public boolean deleteUser(int userId){
        System.out.println("删除缓存");
        return true;
    }

    @Cacheable(value = "common", key = "‘common:user:‘ + #userId")
    public User getCommonUser(int userId) {
        System.out.println("执行此方法,说明没有缓存(测试公共配置是否生效)");
        return new User(userId, "用户名(common)_" + userId, "密码_" + userId);
    }

}

 

 

  f.创建Controller

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("/getUser")
    public User getUser(int userId) {
        return userService.getUser(userId);
    }

    @RequestMapping("/addUser")
    public User addUser(User user){
        return userService.addUser(user);
    }

    @RequestMapping("/deleteUser")
    public boolean deleteUser(int userId){
        return userService.deleteUser(userId);
    }

    @RequestMapping("/getCommonUser")
    public User getCommonUser(int userId) {
        return userService.getCommonUser(userId);
    }

}

 

@Controller
public class HomeController {
    //默认页面
    @RequestMapping("/")
    public String login() {
        return "test";
    }

}

 

 

  g.在 templates 目录下,写书 test.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style type="text/css">
        .row{
            margin:10px 0px;
        }
        .col{
            display: inline-block;
            margin:0px 5px;
        }
    </style>
</head>
<body>
<div>
    <h1>测试</h1>
    <div class="row">
        <label>用户ID:</label><input id="userid-input" type="text" name="userid"/>
    </div>
    <div class="row">
        <div class="col">
            <button id="getuser-btn">获取用户</button>
        </div>
        <div class="col">
            <button id="adduser-btn">添加用户</button>
        </div>
        <div class="col">
            <button id="deleteuser-btn">删除用户</button>
        </div>
        <div class="col">
            <button id="getcommonuser-btn">获取用户(common)</button>
        </div>
    </div>
    <div class="row" id="result-div"></div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    $(function() {
        $("#getuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/getUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#adduser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/addUser",
                data: {
                    id: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#deleteuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/deleteUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text(data);
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#getcommonuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/getCommonUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
    });
</script>
</html>

 

以上是关于Spring Boot 整合 Spring Cache + Redis的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot如何整合Redis

Spring Boot如何整合Redis

Spring Boot:Spring Boot整合FreeMarker

spring boot 系列之四:spring boot 整合JPA

Spring Boot系列Spring Boot整合持久层

Spring Boot 2.X - Spring Boot整合AMQP之RabbitMQ