Spring Boot 使用 Cache 緩存


步驟一:引入 spring-boot-starter-cache 依賴

<!-- 引入Spring緩存依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

步驟二:啟動類上使用注解 @EnableCaching 開啟緩存

package com.haitaiinc.clinicpathservice;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@MapperScan("com.haitaiinc.clinicpathservice.mapper")
@EnableAutoConfiguration(exclude={DruidDataSourceAutoConfigure.class})
@EnableCaching public class ClinicPathServiceApplication {

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

}

步驟三:使用緩存注解

@Service
@CacheConfig(cacheNames = "switchCfgCache")//抽取緩存的公共配置
public class SwitchProjService {
    @Autowired
    SwitchProjDao switchProjDao;

    @Cacheable() public List<SwitchProj> getAllSwitchProj(){
        return switchProjDao.getAllSwitchProj();
    }

    @Cacheable(key = "#id") public SwitchProj getSwitchProjById(String id){
        return switchProjDao.getSwitchProjById(id);
    }
}

Spring Boot Cache 存在以下問題:

  1. 生成 key 過於簡單,容易沖突 switchCfgCache::3
  2. 無法設置過期時間,默認過期時間為永久不過期
  3. 無法配置序列化方式,默認的序列化是 JDK Serialazable

那么為了解決以上問題,我們可以新增配置類,增加一些方法

package com.haitaiinc.clinicpathservice.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.cache.RedisCacheWriter;
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 java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableCaching
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                stringBuilder.append(obj.toString());
            }
            stringBuilder.append("]");

            return stringBuilder.toString();
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl(600), // 默認策略,未配置的 key 會使用這個
                this.getRedisCacheConfigurationMap() // 指定 key 策略
        );
    }

    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
 redisCacheConfigurationMap.put("SwitchCfgList", this.getRedisCacheConfigurationWithTtl(100));

        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;
    }

}

然后對我們的代碼進行修改,注意配置類中標紅的部分和代碼修改后的內容(上面配置類中會被代碼編輯器標出一些紅色,但不影響編譯運行)

@Service
@CacheConfig(cacheNames = "switchCfgCache")//抽取緩存的公共配置
public class SwitchProjService {
    @Autowired
    SwitchProjDao switchProjDao;

    @Cacheable(value="SwitchCfgList", keyGenerator = "simpleKeyGenerator") public List<SwitchProj> getAllSwitchProj(){
        return switchProjDao.getAllSwitchProj();
    }

    @Cacheable(keyGenerator = "simpleKeyGenerator") public SwitchProj getSwitchProjById(String id){
        return switchProjDao.getSwitchProjById(id);
    }
}

下圖顯示的是效果:

 也可以查看到緩存的有效時間

 

Redis 實現分布式集群配置 sessionId 過程

步驟一:引入依賴

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

步驟二:啟動類增加注解 @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 50)

@EnableRedisHttpSession 開啟 Redis Session 緩存

maxInactiveIntervalInSeconds 指定緩存的時間 spring:session:sessions:expires:+‘sessionId’ 的過期時間  

步驟三:測試

@RestController
public class TestController {

    @GetMapping("/setSession")
    public Map<String, Object> setSession (HttpServletRequest request){
        Map<String, Object> map = new HashMap<>();
        request.getSession().setAttribute("request Url", request.getRequestURL());
        map.put("request Url", request.getRequestURL());
        return map;
    }

    @GetMapping("/getSession")
    public Object getSession (HttpServletRequest request){
        Map<String, Object> map = new HashMap<>();
        map.put("sessionIdUrl",request.getSession().getAttribute("request Url"));
        map.put("sessionId", request.getSession().getId());
        return map;
    }
}

效果如下圖所示:

 

官方說明:

https://docs.spring.io/spring/docs/5.2.3.RELEASE/spring-framework-reference/integration.html#cache

參考博文:

https://blog.csdn.net/weixin_43907332/article/details/91610493

https://blog.csdn.net/rubulai/article/details/85015074

https://blog.csdn.net/leiliz/article/details/98035397


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM