一. pom.xm文件引入對應jar包java
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
二. application.yml引入redis服務端配置redis
# redis相關配置 redis: host: 192.168.80.3 port: 6379 database: 0 timeout: 60s # 數據庫鏈接超時時間,springboot2.0 中該參數的類型爲Duration,這裏在配置的時候須要指明單位 # 鏈接池配置,springboot2.0中直接使用jedis或者lettuce配置鏈接池 jedis: pool: # 最大空閒鏈接數 max-idle: 500 # 最小空閒鏈接數 min-idle: 50 # 等待可用鏈接的最大時間,負數爲不限制 max-wait: -1s # 最大活躍鏈接數,負數爲不限制 max-active: -1
說明:Jedis和Lettuce的比較:spring
Jedis :數據庫
直連模式,在多個線程間共享一個 Jedis 實例時是線程不安全的,若是想要在多線程環境下使用 Jedis,須要使用鏈接池,json
每一個線程都去拿本身的 Jedis 實例,當鏈接數量增多時,物理鏈接成本較高。緩存
Lettuce:安全
鏈接是基於Netty的,鏈接實例能夠在多個線程間共享,springboot
因此,一個多線程的應用能夠使用同一個鏈接實例,而不用擔憂併發線程的數量。固然這個也是可伸縮的設計,一個鏈接實例不夠的狀況也能夠按需增長鏈接實例。網絡
經過異步的方式可讓咱們更好的利用系統資源,而不用浪費線程等待網絡或磁盤I/O。多線程
三.RedisConfig 配置RedisTemplate和CacheManage
package com.luckydan.springboot.config; import java.time.Duration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; 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.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * @package: com.luckydan.springboot.config * @description: redis配置文件 * @author: gl * @date: 2018年11月23日 * @version: 1.0.0 */ @EnableCaching @Configuration public class RedisConfig extends CachingConfigurerSupport { @Bean(name="redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<Object>(Object.class); // value值的序列化採用fastJsonRedisSerializer template.setValueSerializer(serializer); template.setHashValueSerializer(serializer); // key的序列化採用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { // 生成一個默認配置,經過config對象便可對緩存進行自定義配置 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 設置緩存的默認過時時間,也是使用Duration設置 config = config.entryTtl(Duration.ofMinutes(1)) .disableCachingNullValues(); // 不緩存空值 // 設置一個初始化的緩存空間set集合 Set<String> cacheNames = new HashSet<>(); cacheNames.add("my-redis-cache1"); cacheNames.add("my-redis-cache2"); // 對每一個緩存空間應用不一樣的配置 Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); configMap.put("my-redis-cache1", config); configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120))); // 使用自定義的緩存配置初始化一個cacheManager RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .initialCacheNames(cacheNames) // 注意這兩句的調用順序,必定要先調用該方法設置初始化的緩存名,再初始化相關的配置 .withInitialCacheConfigurations(configMap) .build(); return cacheManager; } }
說明:在獲取RedisTemplate過程當中須要對key-value鍵值對分別進行序列化操做,能夠使用Springboot自帶的Jackson2JsonRedisSerializer進行序列化,也能夠使用fastjson進行自定義序列化
自定義序列化:略
四.整合Redis須要使用的註解介紹:
1.@Cacheable 能夠標記在方法上,也能夠標記在類上。當標記在方法上時表示該方法是支持緩存的,當標記在類上時則表示該類全部的方法都是支持緩存的。應用到讀取數據的方法上,將先從緩存中讀取該方法的返回值,若是沒
有再從DB獲取數據,而後把數據添加到緩存中
緩存是以鍵值對進行的,值就是方法的返回結果,至於鍵的話,Spring又支持兩種策略,默認策略和自定義策略,須要注意的是當一個支持緩存的方法在對象內部被調用時是不會觸發緩存功能的
。
屬性值:value,key,condition(參考註解@CacheEvcit的屬性值),unless
參數 | 解釋 | example |
unless | 緩存條件:判斷unless,若是返回false,則放入緩存(與Condition相反 )
|
@CachePut (value="user", key="#root.method.name_+#userId" unless="#username eq han") |
condition | 緩存的條件,能夠爲空,使用 SpEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存 @Cacheable 將在執行方法以前( #result還拿不到返回值)判斷condition,若是返回true, 則查緩存; @CachePut 將在執行完方法後(#result就能拿到返回值了)判斷condition,若是返回true, 則放入緩存; @CacheEvcit 當beforeInvocation= false 表示在方法執行以後調用(#result就能拿到返 回值了)且判斷condition,若是返回true,則移除緩存。 |
@CacheEvict (value="user", condition=」#userName.length()>2」) |
2.@CacheEvcit 應用到刪除數據的方法上,調用方法時會從緩存中刪除對應key的數據
屬性值:value,key,condition,allentries,beforeInvocation
參數 | 解釋 | example |
value | 緩存的名稱,在 spring 配置文件中定義, 必須指定至少一個 |
例如: @Cacheable(value=」mycache」) @Cacheable(value={」cache1」,」cache2」} |
key | 緩存的 key,能夠爲空,若是指定要按照 SpEL 表達式編寫,若是不指定,則缺省 按照方法的全部參數進行組合 |
@CacheEvict (value=」user」,key=」#userName」) |
condition | 緩存的條件,能夠爲空,使用 SpEL 編寫, 返回 true 或者 false,只有爲 true 才進行 緩存 |
@CacheEvict (value=」user」,condition=」#userName.length()>2」) |
allentries | 是否清空全部緩存內容,缺省爲 false, 若是指定爲 true,則方法調用後將當即清 空全部緩存 |
@CachEvict(value=」user」,allEntries=true) |
beforeInvocation | 是否在方法執行前就清空,缺省爲 false, 若是指定爲 true,則在方法尚未執行 的時候就清空緩存,缺省狀況下,若是 方法執行拋出異常,則不會清空緩存 |
@CachEvict (value=」user」,beforeInvocation=true) |
3.@CachePut 應用到寫數據的方法上,如新增/修改方法,調用方法時會自動把相應的數據放入緩存,
具體步驟以下:Spring在每次執行前都會檢查Cache中是否存在相同key的緩存元素,若是存在就再也不執行該方法,而是直接從緩存中獲取結果進行返回,不然纔會執行並將返回結果存入指定的緩存中。
與@Cacheable的區別:執行前不會去檢查緩存中是否存在以前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中
屬性值:value,key,condition,unless(參考註解@CacheEvcit的屬性值),unless
4. @CacheConfig 屬於類級別的註解,當方法上的註解未註明value時,以@CacheConfig的value屬性爲準,當方法上註明value時,以方法上的註解value屬性爲準
5. @Caching 可能組合多個Cache註解使用;好比用戶新增成功後,咱們要添加id–>user;username—>user;email—>user的緩存;此時就須要@Caching組合多個註解標籤了
ex:能夠使用以下方式使用:
@Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) public User save(User user) {}
ex:也能夠使用自定義註解的方式實現相應的功能
/** * 自定義註解 */ @Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface UserSaveCache { }
將自定義註解添加到指定的方法上:這種方法會使代碼很乾淨(強力推薦)
1 @UserSaveCache 2 public User save(User user){}