CacheManager管理器的擴充支援
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的實作類
複制代碼
緩存注解
下面是緩存公用接口注釋,适用于任何緩存類型。
@EnableCaching
在啟動類注解@EnableCaching開啟緩存。
@SpringBootApplication
@EnableCaching //開啟緩存
public class DemoApplication{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
複制代碼
@Cacheable
配置findByName函數的傳回值将被加入緩存。同時在查詢時,會先從緩存中擷取,若不存在才再發起對資料庫的通路。
該注解主要有下面幾個參數:
- value、cacheNames:兩個等同的參數(cacheNames為Spring4新增,作為value的别名),用于指定緩存存儲的集合名。
- 由于Spring4中新增了@CacheConfig,是以在Spring3中原本必須有的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 SampleServiceImpl implements SampleService {
@Override
@Cacheable(value = {"newJob"},key = "#p0")
public List<NewJob> findAllLimit(int num) {
return botRelationRepository.findAllLimit(num);
}
.....
}
複制代碼
@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;
}
複制代碼
@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();
}
複制代碼
@CacheConfig
統一配置本類的緩存注解的屬性,在類上面統一定義緩存的名字,方法上面就不用标注了,當标記在一個類上時則表示該類所有的方法都是支援緩存的
@CacheConfig(cacheNames = {"myCache"})
public class SampleServiceImpl implements SampleService {
@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 |
注意
當我們要使用root對象的屬性作為key時,我們也可以将“#root”省略,因為Spring預設使用的就是root對象的屬性。 如
@Cacheable(key = "targetClass + methodName +#p0")
複制代碼
使用方法參數時,可以直接使用“#參數名”或者“#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 | |
其他類型 | ?.,?[…],![…],^[…],$[…] |
不同Cache的實作機制
ConcurrentMap Cache的實作方案
SpringBoot預設使用的是SimpleCacheConfiguration,使用ConcurrentMapCacheManager來實作緩存,ConcurrentMapCache實質是一個ConcurrentHashMap集合對象java内置,是以無需引入其他依賴,也沒有額外的配置
ConcurrentMapCache的自動裝配聲明在SimpleCacheConfiguration中,如果需要也可對它進行額外的裝配
//注冊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算法實作,支援多種緩存過期政策。具體檢視這裡。
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不可以同時使用
導入依賴
<!-- 使用 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>
複制代碼
通過yaml配置
通過配置檔案來設定Caffeine
spring:
cache:
cache-names: outLimit,notOutLimit
caffeine:
spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s,refreshAfterWrite=7s #
type: caffeine
複制代碼
通過bean裝配
@Bean
@Primary
public CacheManager cacheManagerWithCaffeine() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
Caffeine caffeine = Caffeine.newBuilder()
.initialCapacity() //cache的初始容量值
.maximumSize() //maximumSize用來控制cache的最大緩存數量,maximumSize和maximumWeight不可以同時使用,
.maximumWeight() //控制最大權重
.expireAfter(customExpireAfter) //自定義過期
.refreshAfterWrite(, TimeUnit.SECONDS); //使用refreshAfterWrite必須要設定cacheLoader
cacheManager.setCaffeine(caffeine);
cacheManager.setCacheLoader(cacheLoader); //緩存加載方案
cacheManager.setCacheNames(getNames()); //緩存名稱清單
cacheManager.setAllowNullValues(false);
return cacheManager;
}
複制代碼
配置檔案結合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;
}
複制代碼
實作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。
EhCache
EhCache 是一個純Java的程序内緩存架構,具有快速、精幹等特點,是Hibernate中預設CacheProvider。Ehcache是一種廣泛使用的開源Java分布式緩存。主要面向通用緩存,Java EE和輕量級容器。它具有記憶體和磁盤存儲,緩存加載器,緩存擴充,緩存異常處理程式,一個gzip緩存servlet過濾器,支援REST和SOAP api等特點。
導入依賴
引入springboot-cache和ehcache。需要注意,EhCache不需要配置version,SpringBoot的根pom已經內建了。
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
複制代碼
加入配置:
spring.cache.type=ehcache # 配置ehcache緩存
spring.cache.ehcache.config=classpath:/ehcache.xml # 指定ehcache配置檔案路徑 ,可以不用寫,因為預設就是這個路徑,SpringBoot會自動掃描
複制代碼
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>
複制代碼
裝配
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 Cache
Redis 優勢
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的資料類型 – Redis支援二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料類型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
- 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性
- 分布式橫向擴充
導入依賴
不需要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>
複制代碼
配置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這時候已經可以啟動程式了。
裝配
如果需要自定義緩存配置可以通過,繼承CachingConfigurerSupport類,手動裝配,如果一切使用預設配置可不必
裝配序列化類型
@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;
}
複制代碼
裝配過期時間
/**
* 通過RedisCacheManager配置過期時間
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours()); // 設定緩存有效期一小時
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
複制代碼
自定義緩存配置檔案,繼承 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);
}
}