日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

CacheManager管理器的擴(kuò)展支持

Spring的抽象控制機(jī)制,即允許綁定不同的緩存解決方案(如Caffeine、Ehcache等),但本身不直接提供緩存功能的實(shí)現(xiàn)。它支持注解方式使用緩存,非常方便。

SpringBoot在Annotation的層面實(shí)現(xiàn)了數(shù)據(jù)緩存的功能,基于Spring的AOP技術(shù)。所有的緩存配置只是在Annotation層面配置,像聲明式事務(wù)一樣。

Spring定義了CacheManager和Cache接口統(tǒng)一不同的緩存技術(shù)。其中CacheManager是Spring提供的各種緩存技術(shù)的抽象接口。而Cache接口包含緩存的各種操作。

Cache接口下Spring提供了各種xxxCache的實(shí)現(xiàn),如redisCache,EhCacheCache ,ConcurrentMapCache等;

緩存技術(shù)類型與CacheManger

針對(duì)不同的緩存技術(shù),需要實(shí)現(xiàn)不同的cacheManager,Spring定義了如下的cacheManger實(shí)現(xiàn)。

CacheManger

描述

SimpleCacheManager

使用簡(jiǎn)單Collection來(lái)存儲(chǔ)緩存,主要用于測(cè)試

ConcurrentMapCacheManager

使用ConcurrentMap作為緩存技術(shù)(默認(rèn)),需要顯式的刪除緩存,無(wú)過期機(jī)制

NoOpCacheManager

僅測(cè)試用途,不會(huì)實(shí)際存儲(chǔ)緩存

EhCacheCacheManager

使用EhCache作為緩存技術(shù),以前在hibernate的時(shí)候經(jīng)常用

GuavaCacheManager

使用google guava的GuavaCache作為緩存技術(shù)(1.5版本已不建議使用)

CaffeineCacheManager

是使用JAVA8對(duì)Guava緩存的重寫,spring5(springboot2)開始用Caffeine取代guava

HazelcastCacheManager

使用Hazelcast作為緩存技術(shù)

JCacheCacheManager

使用JCache標(biāo)準(zhǔn)的實(shí)現(xiàn)作為緩存技術(shù),如Apache Commons JCS

RedisCacheManager

使用Redis作為緩存技術(shù)


常規(guī)的SpringBoot已經(jīng)為我們自動(dòng)配置了EhCache、Collection、Guava、ConcurrentMap等緩存,默認(rèn)使用ConcurrentMapCacheManager。

SpringBoot的Application.properties配置文件,使用spring.cache前綴的屬性進(jìn)行配置。


緩存依賴

開始使用前需要導(dǎo)入依賴spring-boot-starter-cache為基礎(chǔ)依賴,其他依賴根據(jù)使用不同的緩存技術(shù)選擇加入,默認(rèn)情況下使用ConcurrentMapCache不需要引用任何依賴。

<!-- 基礎(chǔ)依賴 -->
<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>
復(fù)制代碼

application配置

spring.cache.type= #緩存的技術(shù)類型,可選 generic,ehcache,hazelcast,infinispan,jcache,redis,guava,simple,none
spring.cache.cache-names= #應(yīng)用程序啟動(dòng)創(chuàng)建緩存的名稱,必須將所有注釋為@Cacheable緩存name(或value)羅列在這里,否者:Cannot find cache named 'xxx' for Builder[xx] caches=[sysItem] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
#以下根據(jù)不同緩存技術(shù)選擇配置
spring.cache.ehcache.config= #EHCache的配置文件位置
spring.caffeine.spec= #caffeine類型創(chuàng)建緩存的規(guī)范。查看CaffeineSpec了解更多關(guān)于規(guī)格格式的細(xì)節(jié)
spring.cache.infinispan.config= #infinispan的配置文件位置
spring.cache.jcache.config= #jcache配置文件位置
spring.cache.jcache.provider= #當(dāng)多個(gè)jcache實(shí)現(xiàn)類時(shí),指定選擇jcache的實(shí)現(xiàn)類
復(fù)制代碼

緩存注解

下面是緩存公用接口注釋,適用于任何緩存類型。

@EnableCaching

在啟動(dòng)類注解@EnableCaching開啟緩存。

@SpringBootApplication
@EnableCaching  //開啟緩存
public class DemoApplication{     
   public static void mAIn(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}
復(fù)制代碼

@Cacheable

配置findByName函數(shù)的返回值將被加入緩存。同時(shí)在查詢時(shí),會(huì)先從緩存中獲取,若不存在才再發(fā)起對(duì)數(shù)據(jù)庫(kù)的訪問。

該注解主要有下面幾個(gè)參數(shù):

  • value、cacheNames:兩個(gè)等同的參數(shù)(cacheNames為Spring4新增,作為value的別名),用于指定緩存存儲(chǔ)的集合名。
    • 由于Spring4中新增了@CacheConfig,因此在Spring3中原本必須有的value屬性,也成為非必需項(xiàng)了。
  • key:緩存對(duì)象存儲(chǔ)在Map集合中的key值,非必需,缺省按照函數(shù)的所有參數(shù)組合作為key值,若自己配置需使用SpEL表達(dá)式,比如:@Cacheable(key = “#p0”):使用函數(shù)第一個(gè)參數(shù)作為緩存的key值。
  • condition:緩存對(duì)象的條件,非必需,也需使用SpEL表達(dá)式,只有滿足表達(dá)式條件的內(nèi)容才會(huì)被緩存,比如:@Cacheable(key = “#p0”, condition = “#p0.length() < 3”),表示只有當(dāng)?shù)谝粋€(gè)參數(shù)的長(zhǎng)度小于3的時(shí)候才會(huì)被緩存
  • unless:另外一個(gè)緩存條件參數(shù),非必需,需使用SpEL表達(dá)式。它不同于condition參數(shù)的地方在于它的判斷時(shí)機(jī),該條件是在函數(shù)被調(diào)用之后才做判斷的,所以它可以通過對(duì)result進(jìn)行判斷。
  • keyGenerator:用于指定key生成器,非必需。若需要指定一個(gè)自定義的key生成器,我們需要去實(shí)現(xiàn)org.springframework.cache.interceptor.KeyGenerator接口,并使用該參數(shù)來(lái)指定。
    • 需要注意的是:該參數(shù)與key是互斥的。
  • cacheManager:用于指定使用哪個(gè)緩存管理器,非必需。只有當(dāng)有多個(gè)時(shí)才需要使用
  • cacheResolver:用于指定使用那個(gè)緩存解析器,非必需。需通過org.springframework.cache.interceptor.CacheResolver接口來(lái)實(shí)現(xiàn)自己的緩存解析器,并用該參數(shù)指定。
public class SampleServiceImpl implements SampleService {
     @Override
     @Cacheable(value = {"newJob"},key = "#p0")
     public List<NewJob> findAllLimit(int num) {
         return botRelationRepository.findAllLimit(num);
     }
        .....
}
復(fù)制代碼

@CachePut

針對(duì)方法配置,能夠根據(jù)方法的請(qǐng)求參數(shù)對(duì)其結(jié)果進(jìn)行緩存,和 @Cacheable不同的是,它每次都會(huì)觸發(fā)真實(shí)方法的調(diào)用 。

簡(jiǎn)單來(lái)說(shuō)就是用戶更新緩存數(shù)據(jù)。但需要注意的是該注解的value 和key必須與要更新的緩存相同,也就是與@Cacheable 相同。

示例:

 //按條件更新緩存
@CachePut(value = "newJob", key = "#p0") 
public NewJob updata(NewJob job) {
     NewJob newJob = newJobDao.findAllById(job.getId());
     newJob.updata(job);
     return job;
}
復(fù)制代碼

@CacheEvict

配置于函數(shù)上,通常用在刪除方法上,用來(lái)從緩存中移除相應(yīng)數(shù)據(jù)。除了同@Cacheable一樣的參數(shù)之外,它還有下面兩個(gè)參數(shù):

  • allEntries:非必需,默認(rèn)為false。當(dāng)為true時(shí),會(huì)移除所有數(shù)據(jù)。如:@CachEvict(value=”testcache”,allEntries=true)
  • beforeInvocation:非必需,默認(rèn)為false,會(huì)在調(diào)用方法之后移除數(shù)據(jù)。當(dāng)為true時(shí),會(huì)在調(diào)用方法之前移除數(shù)據(jù)。 如:
@CachEvict(value=”testcache”,beforeInvocation=true)
        @Cacheable(value = "emp",key = "#p0.id")
        public NewJob save(NewJob job) {
            newJobDao.save(job);
            return job;
        }
        //清除一條緩存,key為要清空的數(shù)據(jù)
        @CacheEvict(value="emp",key="#id")
        public void delect(int id) {
            newJobDao.deleteAllById(id);
        }
        //方法調(diào)用后清空所有緩存
        @CacheEvict(value="accountCache",allEntries=true)
        public void delectAll() {
            newJobDao.deleteAll();
        }
        //方法調(diào)用前清空所有緩存
        @CacheEvict(value="accountCache",beforeInvocation=true)
        public void delectAll() {
            newJobDao.deleteAll();
        }
復(fù)制代碼

@CacheConfig

統(tǒng)一配置本類的緩存注解的屬性,在類上面統(tǒng)一定義緩存的名字,方法上面就不用標(biāo)注了,當(dāng)標(biāo)記在一個(gè)類上時(shí)則表示該類所有的方法都是支持緩存的

    @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);
        }
        .....
    }
復(fù)制代碼

SpEL上下文數(shù)據(jù)

Spring Cache提供了一些供我們使用的SpEL上下文數(shù)據(jù),直接摘自Spring官方文檔:

名稱

位置

描述

示例

methodName

root對(duì)象

當(dāng)前被調(diào)用的方法名

#root.methodname

method

root對(duì)象

當(dāng)前被調(diào)用的方法

#root.method.name

target

root對(duì)象

當(dāng)前被調(diào)用的目標(biāo)對(duì)象實(shí)例

#root.target

targetClass

root對(duì)象

當(dāng)前被調(diào)用的目標(biāo)對(duì)象的類

#root.targetClass

args

root對(duì)象

當(dāng)前被調(diào)用的方法的參數(shù)列表

#root.args[0]

caches

root對(duì)象

當(dāng)前方法調(diào)用使用的緩存列表

#root.caches[0].name

Argument Name

執(zhí)行上下文

當(dāng)前被調(diào)用的方法的參數(shù),如findArtisan(Artisan artisan),可以通過#artsian.id獲得參數(shù)

#artsian.id

result

執(zhí)行上下文

方法執(zhí)行后的返回值(僅當(dāng)方法執(zhí)行后的判斷有效,如 unless cacheEvict的beforeInvocation=false)

#result

注意

當(dāng)我們要使用root對(duì)象的屬性作為key時(shí),我們也可以將“#root”省略,因?yàn)镾pring默認(rèn)使用的就是root對(duì)象的屬性。 如

@Cacheable(key = "targetClass + methodName +#p0")
復(fù)制代碼

使用方法參數(shù)時(shí),可以直接使用“#參數(shù)名”或者“#p參數(shù)index”。 如:

@Cacheable(value="users", key="#id")
@Cacheable(value="users", key="#p0")
復(fù)制代碼

SpEL提供了多種運(yùn)算符

類型

運(yùn)算符

 

關(guān)系

<,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne

 

算術(shù)

+,- ,* ,/,%,^

 

邏輯

&&,

,!,and,or,not,between,instanceof

條件

?: (ternary),?: (elvis)

 

正則表達(dá)式

matches

 

其他類型

?.,?[…],![…],^[…],$[…]

 

不同Cache的實(shí)現(xiàn)機(jī)制

 

ConcurrentMap Cache的實(shí)現(xiàn)方案

SpringBoot默認(rèn)使用的是SimpleCacheConfiguration,使用ConcurrentMapCacheManager來(lái)實(shí)現(xiàn)緩存,ConcurrentMapCache實(shí)質(zhì)是一個(gè)ConcurrentHashMap集合對(duì)象java內(nèi)置,所以無(wú)需引入其他依賴,也沒有額外的配置

ConcurrentMapCache的自動(dòng)裝配聲明在SimpleCacheConfiguration中,如果需要也可對(duì)它進(jìn)行額外的裝配

//注冊(cè)id為cacheManager,類型為ConcurrentMapCacheManager的bean
@Bean
public ConcurrentMapCacheManager cacheManager() {
    ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); //實(shí)例化ConcurrentMapCacheManager
    List<String> cacheNames = this.cacheProperties.getCacheNames(); //讀取配置文件,如果配置有spring.cache.cache-names=xx,xx,則進(jìn)行配置cacheNames,默認(rèn)是沒有配置的
    if (!cacheNames.isEmpty()) {
       cacheManager.setCacheNames(cacheNames);
    }
    return this.customizerInvoker.customize(cacheManager); 
    }
復(fù)制代碼

調(diào)用CacheManagerCustomizers#customize 進(jìn)行個(gè)性化設(shè)置,在該方法中是遍歷其持有的List。

Caffeine Cache

Caffeine是使用Java8對(duì)Guava緩存的重寫版本,在Spring Boot 2.0中將取代,基于LRU算法實(shí)現(xiàn),支持多種緩存過期策略。具體查看這里。

Caffeine參數(shù)說(shuō)明

initialCapacity=[integer]: 初始的緩存空間大小
maximumSize=[long]: 緩存的最大條數(shù)
maximumWeight=[long]: 緩存的最大權(quán)重
expireAfterAccess=[duration]: 最后一次寫入或訪問后經(jīng)過固定時(shí)間過期
expireAfterWrite=[duration]: 最后一次寫入后經(jīng)過固定時(shí)間過期
refreshAfterWrite=[duration]: 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過固定的時(shí)間間隔,刷新緩存 refreshAfterWrite requires a LoadingCache
weakKeys: 打開key的弱引用
weakValues:打開value的弱引用
softValues:打開value的軟引用
recordStats:開發(fā)統(tǒng)計(jì)功能
復(fù)制代碼

注意:

refreshAfterWrite必須實(shí)現(xiàn)LoadingCache,跟expire的區(qū)別是,指定時(shí)間過后,expire是remove該key,下次訪問是同步去獲取返回新值,而refresh則是指定時(shí)間后,不會(huì)remove該key,下次訪問會(huì)觸發(fā)刷新,新值沒有回來(lái)時(shí)返回舊值

  • expireAfterWrite和expireAfterAccess同時(shí)存在時(shí),以expireAfterWrite為準(zhǔn)。
  • maximumSize和maximumWeight不可以同時(shí)使用
  • weakValues和softValues不可以同時(shí)使用

導(dǎo)入依賴

<!-- 使用  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>
復(fù)制代碼

通過yaml配置

通過配置文件來(lái)設(shè)置Caffeine

spring:
  cache:
    cache-names: outLimit,notOutLimit
    caffeine:
      spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s,refreshAfterWrite=7s #
      type: caffeine 
復(fù)制代碼

通過bean裝配

@Bean
@Primary
public CacheManager cacheManagerWithCaffeine() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        Caffeine caffeine = Caffeine.newBuilder()
                .initialCapacity() //cache的初始容量值
                .maximumSize() //maximumSize用來(lái)控制cache的最大緩存數(shù)量,maximumSize和maximumWeight不可以同時(shí)使用,
                .maximumWeight() //控制最大權(quán)重
                .expireAfter(customExpireAfter) //自定義過期
                .refreshAfterWrite(, TimeUnit.SECONDS);  //使用refreshAfterWrite必須要設(shè)置cacheLoader
        cacheManager.setCaffeine(caffeine);
        cacheManager.setCacheLoader(cacheLoader); //緩存加載方案
        cacheManager.setCacheNames(getNames());   //緩存名稱列表
        cacheManager.setAllowNullValues(false);
        return cacheManager;
    }
復(fù)制代碼

配置文件結(jié)合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;
    }
復(fù)制代碼

實(shí)現(xiàn)CacheLoader

CacheLoader是cache的一種加載策略,key不存在或者key過期之類的都可以通過CacheLoader來(lái)自定義獲得/重新獲得數(shù)據(jù)。使用refreshAfterWrite必須要設(shè)置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;
                }
                // 達(dá)到配置文件中的refreshAfterWrite所指定的時(shí)候回處罰這個(gè)事件方法
                @Override
                public Object reload(Object key, Object oldValue) throws Exception {
                    return oldValue; //可以在這里處理重新加載策略,本例子,沒有處理重新加載,只是返回舊值。
                }
            };
            return cacheLoader;
        }
    }
復(fù)制代碼

CacheLoader實(shí)質(zhì)是一個(gè)監(jiān)聽,處上述load與reload還包含,expireAfterCreate,expireAfterUpdate,expireAfterRead等可以很靈活的配置CacheLoader。

EhCache

EhCache 是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是Hibernate中默認(rèn)CacheProvider。Ehcache是一種廣泛使用的開源Java分布式緩存。主要面向通用緩存,Java EE和輕量級(jí)容器。它具有內(nèi)存和磁盤存儲(chǔ),緩存加載器,緩存擴(kuò)展,緩存異常處理程序,一個(gè)gzip緩存servlet過濾器,支持REST和SOAP api等特點(diǎn)。

導(dǎo)入依賴

引入springboot-cache和ehcache。需要注意,EhCache不需要配置version,SpringBoot的根pom已經(jīng)集成了。

<dependency>
   <groupId>net.sf.ehcache</groupId>
   <artifactId>ehcache</artifactId>
</dependency>
復(fù)制代碼

加入配置:

spring.cache.type=ehcache # 配置ehcache緩存
spring.cache.ehcache.config=classpath:/ehcache.xml # 指定ehcache配置文件路徑 ,可以不用寫,因?yàn)槟J(rèn)就是這個(gè)路徑,SpringBoot會(huì)自動(dòng)掃描
復(fù)制代碼

ehcache配置文件

EhCache的配置文件ehcache.xml只需要放到類路徑下面,SpringBoot會(huì)自動(dòng)掃描。

    <ehcache>
     
        <!--
            磁盤存儲(chǔ):指定一個(gè)文件目錄,當(dāng)EHCache把數(shù)據(jù)寫到硬盤上時(shí),將把數(shù)據(jù)寫到這個(gè)文件目錄下
            path:指定在硬盤上存儲(chǔ)對(duì)象的路徑
            path可以配置的目錄有:
                user.home(用戶的家目錄)
                user.dir(用戶當(dāng)前的工作目錄)
                java.io.tmpdir(默認(rèn)的臨時(shí)目錄)
                ehcache.disk.store.dir(ehcache的配置目錄)
                絕對(duì)路徑(如:d:\ehcache)
            查看路徑方法:String tmpDir = System.getProperty("java.io.tmpdir");
         -->
        <diskStore path="java.io.tmpdir" />
        <!--
            defaultCache:默認(rèn)的緩存配置信息,如果不加特殊說(shuō)明,則所有對(duì)象按照此配置項(xiàng)處理
            maxElementsInMemory:設(shè)置了緩存的上限,最多存儲(chǔ)多少個(gè)記錄對(duì)象
            eternal:代表對(duì)象是否永不過期 (指定true則下面兩項(xiàng)配置需為0無(wú)限期)
            timeToIdleSeconds:最大的發(fā)呆時(shí)間 /秒
            timeToLiveSeconds:最大的存活時(shí)間 /秒
            overflowToDisk:是否允許對(duì)象被寫入到磁盤
            說(shuō)明:下列配置自緩存建立起600秒(10分鐘)有效 。
            在有效的600秒(10分鐘)內(nèi),如果連續(xù)120秒(2分鐘)未訪問緩存,則緩存失效。
            就算有訪問,也只會(huì)存活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>
復(fù)制代碼

裝配

SpringBoot會(huì)為我們自動(dòng)配置 EhCacheCacheManager 這個(gè)Bean,如果想自定義設(shè)置一些個(gè)性化參數(shù)時(shí),通過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;
        }  
     
    }  
復(fù)制代碼

Redis Cache

Redis 優(yōu)勢(shì)

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數(shù)據(jù)類型 – Redis支持二進(jìn)制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個(gè)操作是原子性的。多個(gè)操作也支持事務(wù),即原子性,通過MULTI和EXEC指令包起來(lái)。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性
  • 分布式橫向擴(kuò)展

導(dǎo)入依賴

不需要spring-boot-starter-cache

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
復(fù)制代碼

當(dāng)你導(dǎo)入這一個(gè)依賴時(shí),SpringBoot的CacheManager就會(huì)使用RedisCache。

Redis使用模式使用pool2連接池,在需要時(shí)引用下面的依賴

    <!-- 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>
復(fù)制代碼

配置Redis

    spring.redis.database=1 # Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)
    spring.redis.host=127.0.0.1 # Redis服務(wù)器地址
    spring.redis.port=6379 # Redis服務(wù)器連接端口
    spring.redis.password= # Redis服務(wù)器連接密碼(默認(rèn)為空)
    spring.redis.pool.max-active=1000 # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
    spring.redis.pool.max-wait=-1 # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
    spring.redis.pool.max-idle=10 # 連接池中的最大空閑連接
    spring.redis.pool.min-idle=2 # 連接池中的最小空閑連接
    spring.redis.timeout=0 # 連接超時(shí)時(shí)間(毫秒)
復(fù)制代碼

如果你的Redis這時(shí)候已經(jīng)可以啟動(dòng)程序了。

裝配

如果需要自定義緩存配置可以通過,繼承CachingConfigurerSupport類,手動(dòng)裝配,如果一切使用默認(rèn)配置可不必

裝配序列化類型

        @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;
        }
復(fù)制代碼

裝配過期時(shí)間  

     /**
         * 通過RedisCacheManager配置過期時(shí)間
         *
         * @param redisConnectionFactory
         * @return
         */
        @Bean
        public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofHours()); // 設(shè)置緩存有效期一小時(shí)
            return RedisCacheManager
                    .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                    .cacheDefaults(redisCacheConfiguration).build();
        }
復(fù)制代碼

自定義緩存配置文件,繼承 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;
        }
     
        /**
         * 指定默認(rèn)的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默認(rèn)采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer
         * RedisTemplate默認(rèn)采用的是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 替換默認(rèn)序列化
    //        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);
    //
    //
    //        //設(shè)置value的序列化方式
    //        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    //        //設(shè)置key的序列化方式
    //        redisTemplate.setKeySerializer(new StringRedisSerializer());
    //        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    //        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
     
            //使用fastJson作為默認(rèn)的序列化方式
            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;
     
        }
     
        /**
         * 轉(zhuǎn)換返回的object為json
         * @return
         */
        @Bean
        public HttpMessageConverters fastJsonHttpMessageConverters(){
            // 1、需要先定義一個(gè)converter 轉(zhuǎn)換器
            FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
            // 2、添加fastJson 的配置信息,比如:是否要格式化返回的json數(shù)據(jù)
            FastJsonConfig fastJsonConfig = new FastJsonConfig();
            fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
            // 3、在convert 中添加配置信息
            fastConverter.setFastJsonConfig(fastJsonConfig);
            // 4、將convert 添加到converters當(dāng)中
            HttpMessageConverter<?> converter = fastConverter;
            return new HttpMessageConverters(converter);
        }
     
    }

分享到:
標(biāo)簽:Spring
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定