Spring Cache 是Spring 提供的一整套的缓存解决方案,它不是具体的缓存实现,它只提供一整套的接口和代码规范、配置、注解等,用于整合各种缓存方案,比如Redis、Caffeine、Guava Cache、Ehcache。使用注解方式替代原有硬编码方式缓存,语法更加简单优雅!
网上教程有点少,只记录一下使用方法
添加在公共模块
- 添加依赖
pom.xml
代码语言:javascript复制<!-- 缓存依赖 -->
<!--spring-cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis连接池-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
- 编写缓存配置
package org.ssm.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
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.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.time.Duration;
/**
* @author shaoshao
* @Date 2022/11/29 20:59
* @Description: 缓存配置类 放置配置的方法,子模板继承和复用
*/
public class CacheConfiguration {
//配置缓存manager
@Bean
@Primary //同类型,多个bean,默认生效! 默认缓存时间1小时! 可以选择!
public RedisCacheManager cacheManagerHour(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration instanceConfig = instanceConfig(1 * 3600L);//缓存时间1小时
//构建缓存对象
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(instanceConfig)
.transactionAware()
.build();
}
//缓存一天配置
@Bean
public RedisCacheManager cacheManagerDay(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration instanceConfig = instanceConfig(24 * 3600L);//缓存时间1小时
//构建缓存对象
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(instanceConfig)
.transactionAware()
.build();
}
/**
* 实例化具体的缓存配置!
* 设置缓存方式JSON
* 设置缓存时间 单位秒
*
* @param ttl
* @return
*/
private RedisCacheConfiguration instanceConfig(Long ttl) {
//设置jackson序列化工具
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer
= new Jackson2JsonRedisSerializer<Object>(Object.class);
//常见jackson的对象映射器,并设置一些基本属性
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(ttl)) //设置缓存时间
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
}
application-cache.yml
代码语言:javascript复制spring:
cache:
type: redis
redis:
host: 192.168.174.131
port: 6379
jedis: # 设置Redis连接池
pool:
max-wait: 2000ms
min-idle: 2
max-idle: 8
max-active: 10
调用模块
- 激活配置(这里是配置类在另一个模块,调用另一个模块)
application.yml
代码语言:javascript复制spring:
profiles:
active: cache
- 启动类添加注解
package org.ssm.product;
/**
* @author shaoshao
* @version 1.0
* @date 2022/11/17 15:40
*/
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.ssm.clients.CategoryClient;
import org.ssm.clients.SearchClient;
import org.ssm.pojo.Category;
/**
* projectName: b2c-cloud-store
*
* @author:
* description: 启动类
*/
@SpringBootApplication
@MapperScan(basePackages = "org.ssm.product.mapper")
@EnableFeignClients(clients = {CategoryClient.class, SearchClient.class})
@EnableCaching
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class,args);
}
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
- 配置类继承公共模块的配置列
@Configuration
public class CarouselConfiguration extends CacheConfiguration {
}
控制层
代码语言:javascript复制package org.ssm.carousel.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.ssm.carousel.service.CarouselService;
import org.ssm.utils.R;
/**
* @author shaoshao
* @version 1.0
* @date 2022/11/16 15:35
*/
@RestController
@RequestMapping("carousel")
public class CarouselController {
@Autowired
private CarouselService carouselService;
@PostMapping("list")
public R list() {
return carouselService.list();
}
}
实现类接口:CarouselService
代码语言:javascript复制public interface CarouselService {
R list();
}
实现类:CarouselServiceImpl
代码语言:javascript复制package org.ssm.carousel.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.ssm.carousel.mapper.CarouselMapper;
import org.ssm.carousel.service.CarouselService;
import org.ssm.pojo.Carousel;
import org.ssm.utils.R;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author shaoshao
* @version 1.0
* @date 2022/11/16 15:46
*/
@Service
@Slf4j
public class CarouselServiceImpl implements CarouselService {
@Autowired
private CarouselMapper carouselMapper;
@Cacheable(value = "list.carousel", key = "#root.methodName", cacheManager = "cacheManagerDay")
@Override
public R list() {
QueryWrapper<Carousel> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("priority");
List<Carousel> list = carouselMapper.selectList(wrapper);
List<Carousel> collect = list.stream().limit(6).collect(Collectors.toList());
log.info("CarouselServiceImpl.list业务结束,结果是: {}", R.ok(collect));
return R.ok(collect);
}
}
关于缓存的注解使用方法可以看注解的使用这篇博客cache模块