您好,登錄后才能下訂單哦!
這篇文章主要講解了Spring cache如何整合redis,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。
Spring-Cache是Spring3.1引入的基于注解的緩存技術(shù),本質(zhì)上它并不是一個(gè)具體的緩存實(shí)現(xiàn),而是一個(gè)對(duì)緩存使用的抽象,通過(guò)Spring AOP技術(shù),在原有的代碼上添加少量的注解來(lái)實(shí)現(xiàn)將這個(gè)方法轉(zhuǎn)成緩存方法的效果。
本來(lái)想來(lái)個(gè)分析源碼,奈何水平有限,先從實(shí)戰(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() //設(shè)置緩存超時(shí)時(shí)間 30分鐘 .entryTtl(timeOut) //設(shè)置key序列化方式 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) //設(shè)置value序列化方式 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) .disableCachingNullValues(); return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).transactionAware().build(); } }
主要看@EnableCaching注解,這個(gè)注解引入了@Import(CachingConfigurationSelector.class),通過(guò)CachingConfigurationSelector把代理創(chuàng)建類、CacheInterceptor、CacheOperationSource、BeanFactoryCacheOperationSourceAdvisor注入到容器,spring通過(guò)CacheInterceptor攔截器攔截相關(guān)帶有@Cacheable、@CacheEvict、@CachePut注解的方法并執(zhí)行相關(guān)緩存操作。
CacheInterceptor相關(guān)源碼:
@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í)行相關(guān)方法 return invokeOperation(invoker); } } ...省略 }
RedisCache相關(guān)代碼:
public synchronized <T> T get(Object key, Callable<T> valueLoader) { ValueWrapper result = get(key); //緩存中有值則返回 if (result != null) { return (T) result.get(); } //緩存中不存在則執(zhí)行相關(guān)方法 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){ } }
測(cè)試:
通過(guò)postman觸發(fā)相關(guān)方法,現(xiàn)在我們連上redis查看緩存寫入情況
這里我們看到key已經(jīng)寫入,過(guò)期時(shí)間也存在
現(xiàn)在我們刪除緩存
看完上述內(nèi)容,是不是對(duì)Spring cache如何整合redis有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。