Spring 提供了對緩存功能的抽象:即允許綁定不同的緩存解決方案(如Caffeine、Ehcache等),但本身不直接提供緩存功能的實現。它支持注解方式使用緩存,非常方便。
SpringBoot在annotation的層面實現了數據緩存的功能,基於Spring的AOP技術。所有的緩存配置只是在annotation層面配置,像聲明式事務一樣。
Spring定義了CacheManager和Cache接口統一不同的緩存技術。其中CacheManager是Spring提供的各種緩存技術的抽象接口。而Cache接口包含緩存的各種操作。
Cache接口下Spring提供了各種xxxCache的實現,如RedisCache,EhCacheCache ,ConcurrentMapCache等;
一,緩存技術類型與CacheManger
針對不同的緩存技術,需要實現不同的cacheManager,Spring定義了如下的cacheManger實現。
CacheManger | 描述 |
---|---|
SimpleCacheManager | 使用簡單的Collection來存儲緩存,主要用於測試 |
ConcurrentMapCacheManager | 使用ConcurrentMap作為緩存技術(默認),需要顯式的刪除緩存,無過期機制 |
NoOpCacheManager | 僅測試用途,不會實際存儲緩存 |
EhCacheCacheManager | 使用EhCache作為緩存技術,以前在hibernate的時候經常用 |
GuavaCacheManager | 使用google guava的GuavaCache作為緩存技術(1.5版本已不建議使用) |
CaffeineCacheManager | 是使用Java8對Guava緩存的重寫,spring5(springboot2)開始用Caffeine取代guava |
HazelcastCacheManager | 使用Hazelcast作為緩存技術 |
JCacheCacheManager | 使用JCache標准的實現作為緩存技術,如Apache Commons JCS |
RedisCacheManager | 使用Redis作為緩存技術 |
常規的SpringBoot已經為我們自動配置了EhCache、Collection、Guava、ConcurrentMap等緩存,默認使用ConcurrentMapCacheManager
。SpringBoot的application.properties配置文件,使用spring.cache前綴的屬性進行配置。
二,緩存依賴
開始使用前需要導入依賴
spring-boot-starter-cache 為基礎依賴,其他依賴根據使用不同的緩存技術選擇加入,默認情況下使用 ConcurrentMapCache不需要引用任何依賴
<!-- 基礎依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 使用 ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency> <!-- 使用 caffeine https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.6.0</version> </dependency> <!-- 使用 redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
三、application配置
spring.cache.type= #緩存的技術類型,可選 generic,ehcache,hazelcast,infinispan,jcache,redis,guava,simple,none spring.cache.cache-names= #應用程序啟動創建緩存的名稱,必須將所有注釋為@Cacheable緩存name(或value)羅列在這里,否者:Cannot find cache named 'xxx' for Builder[xx] caches=[sysItem] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
#以下根據不同緩存技術選擇配置 spring.cache.ehcache.config= #EHCache的配置文件位置 spring.caffeine.spec= #caffeine類型創建緩存的規范。查看CaffeineSpec了解更多關於規格格式的細節
spring.cache.infinispan.config= #infinispan的配置文件位置 spring.cache.jcache.config= #jcache配置文件位置 spring.cache.jcache.provider= #當多個jcache實現類時,指定選擇jcache的實現類
四、緩存注解
下面是緩存公用接口注釋,使用與任何緩存技術
1,@EnableCaching:在啟動類注解@EnableCaching開啟緩存
@SpringBootApplication @EnableCaching //開啟緩存 public class DemoApplication{ public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
2,@Cacheable:配置了findByName函數的返回值將被加入緩存。同時在查詢時,會先從緩存中獲取,若不存在才再發起對數據庫的訪問。
該注解主要有下面幾個參數:
- value、cacheNames:兩個等同的參數(cacheNames為Spring 4新增,作為value的別名),用於指定緩存存儲的集合名。由於Spring 4中新增了@CacheConfig,因此在Spring 3中原本必須有的value屬性,也成為非必需項了
- key:緩存對象存儲在Map集合中的key值,非必需,缺省按照函數的所有參數組合作為key值,若自己配置需使用SpEL表達式,比如:@Cacheable(key = “#p0”):使用函數第一個參數作為緩存的key值
- condition:緩存對象的條件,非必需,也需使用SpEL表達式,只有滿足表達式條件的內容才會被緩存,比如:@Cacheable(key = “#p0”, condition = “#p0.length() < 3”),表示只有當第一個參數的長度小於3的時候才會被緩存
- unless:另外一個緩存條件參數,非必需,需使用SpEL表達式。它不同於condition參數的地方在於它的判斷時機,該條件是在函數被調用之后才做判斷的,所以它可以通過對result進行判斷。
- keyGenerator:用於指定key生成器,非必需。若需要指定一個自定義的key生成器,我們需要去實現org.springframework.cache.interceptor.KeyGenerator接口,並使用該參數來指定。需要注意的是:該參數與key是互斥的
- cacheManager:用於指定使用哪個緩存管理器,非必需。只有當有多個時才需要使用
- cacheResolver:用於指定使用那個緩存解析器,非必需。需通過org.springframework.cache.interceptor.CacheResolver接口來實現自己的緩存解析器,並用該參數指定。
public class BotRelationServiceImpl implements BotRelationService { @Override @Cacheable(value = {"newJob"},key = "#p0") public List<NewJob> findAllLimit(int num) { return botRelationRepository.findAllLimit(num); } ..... }
3,@CachePut:主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發真實方法的調用 。簡單來說就是用戶更新緩存數據。但需要注意的是該注解的value 和 key 必須與要更新的緩存相同,也就是與@Cacheable 相同。示例:
@CachePut(value = "newJob", key = "#p0") //按條件更新緩存 public NewJob updata(NewJob job) { NewJob newJob = newJobDao.findAllById(job.getId()); newJob.updata(job); return job; }
4,@CacheEvict:配置於函數上,通常用在刪除方法上,用來從緩存中移除相應數據。除了同@Cacheable一樣的參數之外,它還有下面兩個參數:
- allEntries:非必需,默認為false。當為true時,會移除所有數據。如:@CachEvict(value=”testcache”,allEntries=true)
- beforeInvocation:非必需,默認為false,會在調用方法之后移除數據。當為true時,會在調用方法之前移除數據。 如:@CachEvict(value=”testcache”,beforeInvocation=true)
@Cacheable(value = "emp",key = "#p0.id") public NewJob save(NewJob job) { newJobDao.save(job); return job; } //清除一條緩存,key為要清空的數據 @CacheEvict(value="emp",key="#id") public void delect(int id) { newJobDao.deleteAllById(id); } //方法調用后清空所有緩存 @CacheEvict(value="accountCache",allEntries=true) public void delectAll() { newJobDao.deleteAll(); } //方法調用前清空所有緩存 @CacheEvict(value="accountCache",beforeInvocation=true) public void delectAll() { newJobDao.deleteAll(); }
5,@CacheConfig: 統一配置本類的緩存注解的屬性,在類上面統一定義緩存的名字,方法上面就不用標注了,當標記在一個類上時則表示該類所有的方法都是支持緩存的
@CacheConfig(cacheNames = {"myCache"}) public class BotRelationServiceImpl implements BotRelationService { @Override @Cacheable(key = "targetClass + methodName +#p0")//此處沒寫value public List<BotRelation> findAllLimit(int num) { return botRelationRepository.findAllLimit(num); } ..... }
五:SpEL上下文數據
Spring Cache提供了一些供我們使用的SpEL上下文數據,下表直接摘自Spring官方文檔:
名稱 | 位置 | 描述 | 示例 |
---|---|---|---|
methodName | root對象 | 當前被調用的方法名 | #root.methodname |
method | root對象 | 當前被調用的方法 | #root.method.name |
target | root對象 | 當前被調用的目標對象實例 | #root.target |
targetClass | root對象 | 當前被調用的目標對象的類 | #root.targetClass |
args | root對象 | 當前被調用的方法的參數列表 | #root.args[0] |
caches | root對象 | 當前方法調用使用的緩存列表 | #root.caches[0].name |
Argument Name | 執行上下文 | 當前被調用的方法的參數,如findArtisan(Artisan artisan),可以通過#artsian.id獲得參數 | #artsian.id |
result | 執行上下文 | 方法執行后的返回值(僅當方法執行后的判斷有效,如 unless cacheEvict的beforeInvocation=false) | #result |
注意:
1.當我們要使用root對象的屬性作為key時我們也可以將“#root”省略,因為Spring默認使用的就是root對象的屬性。 如
@Cacheable(key = "targetClass + methodName +#p0")
2.使用方法參數時我們可以直接使用“#參數名”或者“#p參數index”。 如:
@Cacheable(value="users", key="#id")
@Cacheable(value="users", key="#p0")
SpEL提供了多種運算符
類型 | 運算符 |
---|---|
關系 | <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne |
算術 | +,- ,* ,/,%,^ |
邏輯 | &&,||,!,and,or,not,between,instanceof |
條件 | ?: (ternary),?: (elvis) |
正則表達式 | matches |
其他類型 | ?.,?[…],![…],^[…],$[…] |
以上的知識點適合你遺忘的時候來查閱,下面正式進入學習!
六:ConcurrentMap Cache
Spring boot默認使用的是SimpleCacheConfiguration,即使用ConcurrentMapCacheManager來實現緩存,ConcurrentMapCache實質是一個ConcurrentHashMap集合對象java內置,所以無需引入其他依賴,也沒有額外的配置
ConcurrentMapCache的自動裝配聲明在SimpleCacheConfiguration中,如果需要也可對它進行額外的裝配
//注冊1個id為cacheManager,類型為ConcurrentMapCacheManager的bean
@Bean public ConcurrentMapCacheManager cacheManager() { ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); //實例化ConcurrentMapCacheManager List<String> cacheNames = this.cacheProperties.getCacheNames(); //讀取配置文件,如果配置有spring.cache.cache-names=xx,xx,則進行配置cacheNames,默認是沒有配置的 if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return this.customizerInvoker.customize(cacheManager); //調用CacheManagerCustomizers#customize 進行個性化設置,在該方法中是遍歷其持有的List }
七:Caffeine Cache
Caffeine是使用Java8對Guava緩存的重寫版本,在Spring Boot 2.0中將取代,基於LRU算法實現,支持多種緩存過期策略。具體查看這里 https://www.cnblogs.com/liujinhua306/p/9808500.html,
1,Caffeine參數說明:
- initialCapacity=[integer]: 初始的緩存空間大小
- maximumSize=[long]: 緩存的最大條數
- maximumWeight=[long]: 緩存的最大權重
- expireAfterAccess=[duration]: 最后一次寫入或訪問后經過固定時間過期
- expireAfterWrite=[duration]: 最后一次寫入后經過固定時間過期
- refreshAfterWrite=[duration]: 創建緩存或者最近一次更新緩存后經過固定的時間間隔,刷新緩存 refreshAfterWrite requires a LoadingCache
- weakKeys: 打開key的弱引用
- weakValues:打開value的弱引用
- softValues:打開value的軟引用
- recordStats:開發統計功能
#注意:
- refreshAfterWrite必須實現LoadingCache,跟expire的區別是,指定時間過后,expire是remove該key,下次訪問是同步去獲取返回新值,而refresh則是指定時間后,不會remove該key,下次訪問會觸發刷新,新值沒有回來時返回舊值
- expireAfterWrite和expireAfterAccess同事存在時,以expireAfterWrite為准。
- maximumSize和maximumWeight不可以同時使用
- weakValues和softValues不可以同時使用
2,導入依賴
<!-- 使用 caffeine https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.6.0</version> </dependency>
3、Caffeine配置
(1)通過配置文件來設置Caffeine
spring: cache: cache-names: outLimit,notOutLimit caffeine: spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s,refreshAfterWrite=7s # type: caffeine
(2)通過bean裝配
@Bean() @Primary public CacheManager cacheManagerWithCaffeine() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); Caffeine caffeine = Caffeine.newBuilder() .initialCapacity(100) //cache的初始容量值 .maximumSize(1000) //maximumSize用來控制cache的最大緩存數量,maximumSize和maximumWeight不可以同時使用, .maximumWeight(100) //控制最大權重 .expireAfter(customExpireAfter) //自定義過期 .refreshAfterWrite(5, TimeUnit.SECONDS); //使用refreshAfterWrite必須要設置cacheLoader cacheManager.setCaffeine(caffeine); cacheManager.setCacheLoader(cacheLoader); //緩存加載方案 cacheManager.setCacheNames(getNames()); //緩存名稱列表 cacheManager.setAllowNullValues(false); return cacheManager; }
(3)配置文件結合Bean裝配
@Value("${caffeine.spec}") private String caffeineSpec;
@Bean(name = "caffeineSpec") public CacheManager cacheManagerWithCaffeineFromSpec(){ CaffeineSpec spec = CaffeineSpec.parse(caffeineSpec); Caffeine caffeine = Caffeine.from(spec); // 或使用 Caffeine caffeine = Caffeine.from(caffeineSpec); CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(caffeine); cacheManager.setCacheNames(getNames()); return cacheManager; }
4,實現cacheLoader
CacheLoader是cache的一種加載策略,key不存在或者key過期之類的都可以通過CacheLoader來自定義獲得/重新獲得數據。使用refreshAfterWrite必須要設置cacheLoader
@Configuration public class CacheConfig {
@Bean public CacheLoader<Object, Object> cacheLoader() { CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() { @Override public Object load(Object key) throws Exception { return null; } // 達到配置文件中的refreshAfterWrite所指定的時候回處罰這個事件方法 @Override public Object reload(Object key, Object oldValue) throws Exception { return oldValue; //可以在這里處理重新加載策略,本例子,沒有處理重新加載,只是返回舊值。 } }; return cacheLoader; }
}
CacheLoader實質是一個監聽,處上述load與reload還包含,expireAfterCreate,expireAfterUpdate,expireAfterRead等可以很靈活的配置CacheLoader,具體詳細配置可查看這里 https://www.jianshu.com/p/15d0a9ce37dd,詳細原理查看:https://www.cnblogs.com/liujinhua306/p/9808500.html
八:EHCache
EhCache 是一個純Java的進程內緩存框架,具有快速、精干等特點,是Hibernate中默認CacheProvider。Ehcache是一種廣泛使用的開源Java分布式緩存。主要面向通用緩存,Java EE和輕量級容器。它具有內存和磁盤存儲,緩存加載器,緩存擴展,緩存異常處理程序,一個gzip緩存servlet過濾器,支持REST和SOAP api等特點。
1,導入依賴
引入springboot-cache
和ehcache
。需要注意,EhCache
不需要配置version
,SpringBoot的根pom已經集成了。
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
2,加入配置:
spring.cache.type=ehcache # 配置ehcache緩存
spring.cache.ehcache.config=classpath:/ehcache.xml # 指定ehcache配置文件路徑 ,可以不用寫,因為默認就是這個路徑,SpringBoot會自動掃描
3,ehcache配置文件
EhCache的配置文件ehcache.xml只需要放到類路徑下面,SpringBoot會自動掃描
<ehcache> <!-- 磁盤存儲:指定一個文件目錄,當EHCache把數據寫到硬盤上時,將把數據寫到這個文件目錄下 path:指定在硬盤上存儲對象的路徑 path可以配置的目錄有: user.home(用戶的家目錄) user.dir(用戶當前的工作目錄) java.io.tmpdir(默認的臨時目錄) ehcache.disk.store.dir(ehcache的配置目錄) 絕對路徑(如:d:\\ehcache) 查看路徑方法:String tmpDir = System.getProperty("java.io.tmpdir"); --> <diskStore path="java.io.tmpdir" /> <!-- defaultCache:默認的緩存配置信息,如果不加特殊說明,則所有對象按照此配置項處理 maxElementsInMemory:設置了緩存的上限,最多存儲多少個記錄對象 eternal:代表對象是否永不過期 (指定true則下面兩項配置需為0無限期) timeToIdleSeconds:最大的發呆時間 /秒 timeToLiveSeconds:最大的存活時間 /秒 overflowToDisk:是否允許對象被寫入到磁盤 說明:下列配置自緩存建立起600秒(10分鍾)有效 。 在有效的600秒(10分鍾)內,如果連續120秒(2分鍾)未訪問緩存,則緩存失效。 就算有訪問,也只會存活600秒。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="true" /> <!-- 按緩存名稱的不同管理策略 --> <cache name="myCache" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="600" overflowToDisk="true" /> </ehcache>
4,裝配
SpringBoot會為我們自動配置 EhCacheCacheManager
這個Bean,如果想自定義設置一些個性化參數時,通過Java Config形式配置。
@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { return new EhCacheCacheManager(ehCacheCacheManager().getObject()); } @Bean public EhCacheManagerFactoryBean ehCacheCacheManager() { EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean(); cmfb.setConfigLocation(new ClassPathResource("ehcache.xml")); cmfb.setShared(true); return cmfb; } }
九:Redis
1,Redis 優勢
- 分布式
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功執行要么失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過MULTI和EXEC指令包起來。
- 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性
2, 導入依賴
就只需要這一個依賴!不需要spring-boot-starter-cache
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
當你導入這一個依賴時,SpringBoot的CacheManager就會使用RedisCache。
Redis使用模式使用pool2連接池,在需要時引用下面的依賴
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.2</version> </dependency>
4,配置Redis
spring.redis.database=1 # Redis數據庫索引(默認為0) spring.redis.host=127.0.0.1 # Redis服務器地址 spring.redis.port=6379 # Redis服務器連接端口 spring.redis.password= # Redis服務器連接密碼(默認為空) spring.redis.pool.max-active=1000 # 連接池最大連接數(使用負值表示沒有限制) spring.redis.pool.max-wait=-1 # 連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.pool.max-idle=10 # 連接池中的最大空閑連接 spring.redis.pool.min-idle=2 # 連接池中的最小空閑連接 spring.redis.timeout=0 # 連接超時時間(毫秒)
如果你的Redis這時候已經可以啟動程序了。
5,裝配
如果需要自定義緩存配置可以通過,繼承CachingConfigurerSupport類,手動裝配,如果一切使用默認配置可不必
(1) 裝配序列化類型
@Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) { // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//value序列化 redisTemplate.afterPropertiesSet(); return redisTemplate; }
(2) 裝配過期時間
/** * 通過RedisCacheManager配置過期時間 * * @param redisConnectionFactory * @return */ @Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofHours(1)); // 設置緩存有效期一小時 return RedisCacheManager .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) .cacheDefaults(redisCacheConfiguration).build(); }
(3) 一個比較完整的裝配類 demo
/** * 自定義緩存配置文件,繼承 CachingConfigurerSupport * Created by huanl on 2017/8/22. */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport{ public RedisConfig() { super(); } /** * 指定使用哪一種緩存 * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { RedisCacheManager rcm = new RedisCacheManager(redisTemplate); return rcm; } /** * 指定默認的key生成方式 * @return */ @Override public KeyGenerator keyGenerator() { KeyGenerator keyGenerator = new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } return sb.toString(); } }; return keyGenerator; } @Override public CacheResolver cacheResolver() { return super.cacheResolver(); } @Override public CacheErrorHandler errorHandler() { return super.errorHandler(); } /** * redis 序列化策略 ,通常情況下key值采用String序列化策略 * StringRedisTemplate默認采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer * RedisTemplate默認采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer * @param factory * @return */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory){ RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); // // 使用Jackson2JsonRedisSerialize 替換默認序列化 // Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // ObjectMapper om = new ObjectMapper(); // om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // jackson2JsonRedisSerializer.setObjectMapper(om); // // // //設置value的序列化方式 // redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // //設置key的序列化方式 // redisTemplate.setKeySerializer(new StringRedisSerializer()); // redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); //使用fastJson作為默認的序列化方式 GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer(); redisTemplate.setDefaultSerializer(genericFastJsonRedisSerializer); redisTemplate.setValueSerializer(genericFastJsonRedisSerializer); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 轉換返回的object為json * @return */ @Bean public HttpMessageConverters fastJsonHttpMessageConverters(){ // 1、需要先定義一個converter 轉換器 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); // 2、添加fastJson 的配置信息,比如:是否要格式化返回的json數據 FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); // 3、在convert 中添加配置信息 fastConverter.setFastJsonConfig(fastJsonConfig); // 4、將convert 添加到converters當中 HttpMessageConverter<?> converter = fastConverter; return new HttpMessageConverters(converter); } }
6,模板編程
除了使用注解,Spring boot集成 Redis 客戶端jedis。封裝Redis 連接池,以及操作模板,可以方便的顯示的在方法的代碼中處理緩存對象
@Autowired private StringRedisTemplate stringRedisTemplate;//操作key-value都是字符串 @Autowired private RedisTemplate redisTemplate;//操作key-value都是對象 @Autowired private RedisCacheManager redisCacheManager; /** * Redis常見的五大數據類型: * stringRedisTemplate.opsForValue();[String(字符串)] * stringRedisTemplate.opsForList();[List(列表)] * stringRedisTemplate.opsForSet();[Set(集合)] * stringRedisTemplate.opsForHash();[Hash(散列)] * stringRedisTemplate.opsForZSet();[ZSet(有序集合)] */ public void test(){ stringRedisTemplate.opsForValue().append("msg","hello"); Cache emp = redisCacheManager.getCache("emp"); emp.put("111", "222"); }