Spring cache整合redis代碼實例
Spring-Cache是Spring3.1引入的基于注解的緩存技術,本質(zhì)上它并不是一個具體的緩存實現(xiàn),而是一個對緩存使用的抽象,通過Spring AOP技術,在原有的代碼上添加少量的注解來實現(xiàn)將這個方法轉(zhuǎn)成緩存方法的效果。
本來想來個分析源碼,奈何水平有限,先從實戰(zhàn)搞起。
先引入依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.1.6.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.3</version> </dependency>
redis配置:
server:
port: 8000
spring:
redis:
host: 23.95.x.x
port: 6379
timeout: 20s
database: 0
jedis:
pool:
max-active: 5
max-idle: 3
max-wait: 5s
password: testtest
配置類:
package me.yanand.config;
import org.springframework.cache.annotation.EnableCaching;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
@EnableCaching
public class RedisConfig{
private Duration timeOut = Duration.ofMinutes(30);
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//設置緩存超時時間 30分鐘
.entryTtl(timeOut)
//設置key序列化方式
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
//設置value序列化方式
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).transactionAware().build();
}
}
主要看@EnableCaching注解,這個注解引入了@Import(CachingConfigurationSelector.class),通過CachingConfigurationSelector把代理創(chuàng)建類、CacheInterceptor、CacheOperationSource、BeanFactoryCacheOperationSourceAdvisor注入到容器,spring通過CacheInterceptor攔截器攔截相關帶有@Cacheable、@CacheEvict、@CachePut注解的方法并執(zhí)行相關緩存操作。
CacheInterceptor相關源碼:
@Nullable
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
if (contexts.isSynchronized()) {
CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
//滿足條件執(zhí)行
if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
Cache cache = context.getCaches().iterator().next();
try {
//這里主要看RedisCache的get方法
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
}
catch (Cache.ValueRetrievalException ex) {
// The invoker wraps any Throwable in a ThrowableWrapper instance so we
// can just make sure that one bubbles up the stack.
throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
}
}
else {
//不滿足直接執(zhí)行相關方法
return invokeOperation(invoker);
}
}
...省略
}
RedisCache相關代碼:
public synchronized <T> T get(Object key, Callable<T> valueLoader) {
ValueWrapper result = get(key);
//緩存中有值則返回
if (result != null) {
return (T) result.get();
}
//緩存中不存在則執(zhí)行相關方法
T value = valueFromLoader(key, valueLoader);
put(key, value);
return value;
}
注解使用:
package me.yanand.dao;
import me.yanand.pojo.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class UserDao {
@Cacheable(cacheNames = "users",key = "#root.targetClass+#name", unless = "#result eq null")
public User getUser(String name){
return new User("張三",30);
}
@CacheEvict(cacheNames = "users", key = "#root.targetClass+#name")
public void delUser(String name){
}
}
測試:

通過postman觸發(fā)相關方法,現(xiàn)在我們連上redis查看緩存寫入情況

這里我們看到key已經(jīng)寫入,過期時間也存在
現(xiàn)在我們刪除緩存

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java狀態(tài)設計模式實現(xiàn)對象狀態(tài)轉(zhuǎn)換的優(yōu)雅方式
Java狀態(tài)設計模式通過將對象的行為和狀態(tài)分離,使對象能夠根據(jù)不同的狀態(tài)進行不同的行為操作。它通過將狀態(tài)抽象成一個獨立的類來實現(xiàn)對狀態(tài)的封裝,從而簡化了復雜的條件判斷和狀態(tài)轉(zhuǎn)換2023-04-04

