ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Boot整合Spring cache缓存

2021-06-13 22:29:25  阅读:158  来源: 互联网

标签:缓存 String get Spring cache Boot userInfo userService id


一、Spring Cache简介

Spring从3.1开始定义了一系列抽象接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们进行缓存开发。Spring Cache 只负责维护抽象层,具体的实现由你的技术选型来决定。将缓存处理和缓存技术解除耦合。

Spring Cache接口为缓存的组件规范定义,包含缓存的各种操作集合,并提供了各种xxxCache的实现,如RedisCache,EhCacheCache,ConcurrentMapCache等;

项目整合Spring Cache后每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过,如果有就直接从缓存中获取结果,没有就调用方法并把结果放到缓存。

 

 

二、缓存注解介绍

对于缓存声明,Spring的缓存提供了一组java注解:

  • @CacheConfig:设置类级别上共享的一些常见缓存设置。

  • @Cacheable:触发缓存写入。

  • @CacheEvict:触发缓存清除。

  • @Caching 将多种缓存操作分组

  • @CachePut:更新缓存(不会影响到方法的运行)。

 

三、集成Spring Cache

1. 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

 

2. 启动类添加@EnableCaching注解

@EnableCaching注解是spring framework中的注解驱动的缓存管理功能,当你在配置类(@Configuration)上使用@EnableCaching注解时,会触发一个post processor,这会扫描每一个spring bean,查看是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。

@EnableCaching
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

 

3. 编写缓存类

@Slf4j
@Service
public class UserService {

    //查询数据库后 数据添加到缓存
    @Cacheable(cacheNames = "cacheManager", key = "'USER:'+#id", unless = "#result == null")
    public Map<String, Object> get(String id) {
        log.info("获取:" + id);
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", "zhangsan");
        return map;
    }

    //清除一条缓存,key为要清空的数据
    @CacheEvict(cacheNames = "cacheManager", key = "'USER:'+#id")
    public void delete(String id) {
        log.info("删除:" + id);
    }


    //修改数据后更新缓存
    @CachePut(cacheNames = "cacheManager", key = "'USER:'+#userInfo['id']", unless = "#result == null")
    public void update(Map<String, Object> userInfo) {
        log.info("新增[修改]:" + userInfo.toString());
    }
}

 

4. 编写测试类

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

 

package com.demo;

import com.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.Map;

@SpringBootTest
class SpringCacheApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", "123");
        userInfo.put("username", "zhangsan");
        System.out.println("新增缓存--------------------------------");
        userService.update(userInfo);
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("删除缓存--------------------------------");
        userService.delete((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
    }
}

 

5. 测试结果

 

四、使用Redis做缓存管理

1. 集成Redis

Spring Boot 2.x中 默认使用lettuce作为默认redis客户端。当然你也可以引入redisson客户端。这两种是非阻塞反应式高级redis客户端。建议放弃阻塞客户端jedis。

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

<!-- lettuce 必备依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

 

2. 在application.properties添加redis配置

server.port=8765

spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=

spring.cache.type=redis

其他配置可通过前缀spring.cache、spring.redis进行配置

 

3. 修改缓存类

@Slf4j
@Service
public class UserService {

    //查询数据库后 数据添加到缓存
    @Cacheable(cacheNames = "redisCacheManager", key = "'USER:'+#id", unless = "#result == null")
    public Map<String, Object> get(String id) {
        log.info("获取:" + id);
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", "zhangsan");
        return map;
    }

    //清除一条缓存,key为要清空的数据
    @CacheEvict(cacheNames = "redisCacheManager", key = "'USER:'+#id")
    public void delete(String id) {
        log.info("删除:" + id);
    }


    //修改数据后更新缓存
    @CachePut(cacheNames = "redisCacheManager", key = "'USER:'+#userInfo['id']", unless = "#result == null")
    public void update(Map<String, Object> userInfo) {
        log.info("新增[修改]:" + userInfo.toString());
    }
}

 

4. 编写测试类

package com.demo;

import com.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.Map;

@SpringBootTest
class SpringCacheApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", "123");
        userInfo.put("username", "zhangsan");
        System.out.println("新增缓存--------------------------------");
        userService.update(userInfo);
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("删除缓存--------------------------------");
        userService.delete((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
    }
}

 

5. 测试结果

 

五、自定义RedisCacheManager

1、自定义RedisCacheManager

@Configuration
public class CacheConfig {

    @Value("#{${spring.cache.redis.defaultTime}}")
    private Integer defaultTime;

    @Value("#{${spring.cache.redis.configMap}}")
    private Map<String, Integer> configMap;

    @Bean
    public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl(defaultTime),
                this.getRedisCacheConfigurationMap()
        );
    }

    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
        Set<Map.Entry<String, Integer>> entries = configMap.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            redisCacheConfigurationMap.put(entry.getKey(), this.getRedisCacheConfigurationWithTtl(entry.getValue()));
        }
        return redisCacheConfigurationMap;
    }

    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                RedisSerializationContext
                        .SerializationPair
                        .fromSerializer(jackson2JsonRedisSerializer)
        )
                .entryTtl(Duration.ofSeconds(seconds));

        return redisCacheConfiguration;
    }

}

 

2. 在application.properties添加下面配置

# 默认缓存过期时间(单位/秒)
spring.cache.redis.defaultTime=18000
# redis缓存时间配置(key:缓存名,value:过期时间/单位秒)
spring.cache.redis.configMap={"USER":18000}

 

3. 修改缓存类

@Slf4j
@Service
@CacheConfig(cacheNames = "USER", cacheManager = "redisCacheManager")
public class User2Service {

    //查询数据库后 数据添加到缓存
    @Cacheable(key = "#id")
    public Map<String, Object> get(String id) {
        log.info("获取:" + id);
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", "zhangsan");
        return map;
    }

    //清除一条缓存,key为要清空的数据
    @CacheEvict(key = "#id")
    public void delete(String id) {
        log.info("删除:" + id);
    }


    //修改数据后更新缓存
    @CachePut(key = "#userInfo['id']")
    public void update(Map<String, Object> userInfo) {
        log.info("新增[修改]:" + userInfo.toString());
    }
}

 

4. 编写测试类

@SpringBootTest
class SpringCacheApplicationTests {

    @Autowired
    private User2Service userService;

    @Test
    void contextLoads() {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", "123");
        userInfo.put("username", "zhangsan");
        System.out.println("新增缓存--------------------------------");
        userService.update(userInfo);
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
        System.out.println("删除缓存--------------------------------");
        userService.delete((String) userInfo.get("id"));
        System.out.println("获取缓存--------------------------------");
        userService.get((String) userInfo.get("id"));
    }
}

 

5. 测试结果

 

标签:缓存,String,get,Spring,cache,Boot,userInfo,userService,id
来源: https://blog.csdn.net/han12398766/article/details/117885391

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有