Spring自帶緩存
如果沒(méi)有使用緩存中間件,Spring Boot會(huì)使用默認(rèn)的緩存,只需要啟用即可
自帶緩存啟用注解
@EnableCaching
緩存配置詳解
//用在類上
@CacheConfig(cacheNames = "bank") 用在類上,方法中則可以省略cacheNames 配置
// 用在方法上
@Cacheable: 先判斷有沒(méi)有緩存,有就取緩存,否則查庫(kù)后再存入緩存,一般用在get 方法上(不支持設(shè)置緩存時(shí)間)
@CachePut: 操作后結(jié)果存入緩存 ,一般用在update上
@CacheEvict: 清除緩存 ,一般用在delete
@Caching 多個(gè)Cache組合使用
@Caching(
put = {
@CachePut(value = "bank",key="#bank.bankId"),
@CachePut(value = "bank",key="#bank.bankNo")
}
)
public BankVO save(){}
自定義緩存注解(@Caching組合,會(huì)讓方法上的注解顯得整個(gè)代碼比較亂)
@Caching(
put = {
@CachePut(value = "bank",key="#bank.bankId"),
@CachePut(value = "bank",key="#bank.bankNo")
}
)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}
value/cacheNames 緩存的名字,必須指定至少一個(gè), 也可以放在CacheConfig()中
key 緩存的key,可以為空,如果指定要按照SpEl表達(dá)式編寫,如果不指定,則按照所有參數(shù)進(jìn)行組合
condition 緩存的條件,可以為空,使用SpEL編寫,返回true、false,只有為true才進(jìn)行緩存
allEntries 是否清空所有緩存內(nèi)容,默認(rèn)為false,如果指定為true,則方法調(diào)用后立即清空所有緩存
beforeInvocation 是否在方法執(zhí)行前就清空,默認(rèn)為false(如果拋了異常則不會(huì)清空緩存),如果指定為true,則在方法還沒(méi)有執(zhí)行的時(shí)候就清空緩存
以下是相關(guān)代碼
@Configuration
@EnableCaching //開(kāi)啟緩存,如果沒(méi)有使用緩存中間件會(huì)使用Spring自帶的緩存,否則使用中間件緩存,這里就會(huì)使用redis緩存中間件
public class CacheConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
RedisSerializer jackson2JsonRedisSerializer = jsonSerializer();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* RedisTemplate默認(rèn)使用的序列化機(jī)制是JdkSerializationRedisSerializer,這里我們是用Jackson2JsonRedisSerializer
* @return
*/
private RedisSerializer jsonSerializer() {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//解決查詢緩存轉(zhuǎn)換異常的問(wèn)題
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
return jackson2JsonRedisSerializer;
}
@Bean
public RedisUtil redisUtils(RedisTemplate<String, Object> template) {
return new RedisUtil(template);
}
/**
* key的生成策略()
* @return
*/
@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();
};
}
/********************以下代碼解決@Cacheable不支持設(shè)置緩存過(guò)期的問(wèn)題**************************/
/**
*
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.getRedisCacheConfigurationWithTtl(600),//默認(rèn)策略,為配置的key會(huì)使用這個(gè)
this.getRedisCacheConfigurationMap() //指定key策略
);
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
// 需要作緩存在這里加上就加一個(gè)put即可
redisCacheConfigurationMap.put("bankId", this.getRedisCacheConfigurationWithTtl(120)); // 120秒后失效
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer())
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
}
業(yè)務(wù)代碼中使用
@Service
// @CacheConfig(cacheNames = "bank") //如果使用該注解,方法中則可以省略cacheNames /value 配置
@Slf4j
public class BankServiceImpl implements IBankService {
@Cacheable(value = "bankId",keyGenerator = "simpleKeyGenerator")
public BankVO getBank(Long bankId) {
log.info("獲取用戶銀行卡,{}",bankId);
BankVO bankVO = new BankVO();
UserBank bank = bankDomain.getBank(bankId);
if(null != bank){
BeanUtils.copyProperties(bank,bankVO);
}
return bankVO;
}
}
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。