2016-06-08 24 views
0

我使用Spring Boot和EhCache開發日曆應用程序。Spring Cache - 生成自定義緩存結果

某些用戶可以請求某個特定周的音樂會,其他人可以請求整個月的音樂會。所有的響應都被緩存了300秒以減少響應時間。

緩存方法的輸入參數是startDate,endDateusername

問題是,當用戶請求整個月的音樂會,然後在同一個月內的一個星期內,該方法將被執行兩次,即使「周」響應可以基於「月「迴應,因爲本週可能是緩存月份的一個子集。

實例:

1. 
INPUT 
startDate:08.06.2016, endDate:07.07.2016, username:exampleUser 
//the method is executed, response cached 
OUTPUT 
concert "Example Concert" on 13.06.2016 

2.

INPUT 
startDate:08.06.2016, endDate:15.06.2016, username:exampleUser 
//the method is executed, response cached 
OUTPUT 
concert "Example Concert" on 13.06.2016 

正如你可以看到的例子中,該方法將被執行兩次,但實際上沒有必要在執行該方法第二個例子,可以從第一個請求中返回的緩存數據中提取響應。

我想創建concerts緩存定製的「發電機」,這將能遍歷所有緩存數據,發現不同的日期範圍是「遏制」要求startDateendDate

這裏是我到目前爲止:

緩存方法:

@Override 
    @CachePut("concerts") 
    public List<Event> refreshEventsCache(String eventsForUser, Date startDate, Date endDate) throws Exception { 

     return fetchEventsFromTheServer(eventsForUser, startDate, endDate); 
    } 


    @Override 
    @Cacheable(value = "concerts") 
    public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception { 

     return fetchEventsFromTheServer(eventsForUser, startDate, endDate); 
    } 

ehcache.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<ehcache> 
    <defaultCache maxElementsInMemory="500" eternal="false" 
        overflowToDisk="false" memoryStoreEvictionPolicy="LFU" /> 

    <diskStore path="java.io.tempdir"/> 

    <cache name="concerts" 
      maxElementsInMemory="5000" 
      eternal="false" 
      timeToIdleSeconds="0" 
      timeToLiveSeconds="300" 
      overflowToDisk="false" 
      memoryStoreEvictionPolicy="LFU" /> 
</ehcache> 

Application.java:

... 
@SpringBootApplication 
@ComponentScan 
@EnableCaching 
@EnableScheduling 
public class SpringBootWebApplication extends SpringBootServletInitializer { 

    public static void main(String[] args) { 
     SpringApplication.run(SpringBootWebApplication.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(applicationClass); 
    } 

    private static Class<SpringBootWebApplication> applicationClass = SpringBootWebApplication.class; 



} 

如何建立 「智能」 高速緩存產生,這將返回緩存的數據子集?

回答

1

你不能因爲下面的方法在這裏使用了Spring的默認緩存機制,

@Override 
@Cacheable(value = "concerts") 
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception { 

    return fetchEventsFromTheServer(eventsForUser, startDate, endDate); 
} 

緩存鍵將基於所有三個參數eventsForUser, startDate, endDate產生。

因此,在您的第二個查詢中,前一個startDateendDate之間的一週內,生成的密鑰將不同,因此會有一個緩存未命中,因此它將直接從數據庫加載。

您有要求,需要實現「智能」緩存這只是一個想法,

你可以注入CacheManager,並用它來獲取基於你所產生的緩存鍵緩存列表。

例如: - 緩存密鑰startDate:08.06.2016,endDate:07.07.2016,用戶名:exampleUser可以是08.06.2016_07.07.2016_exampleUser

您可以使用

Cache cache = cacheManager.getCache("08.06.2016_15.06.2016_exampleUser"); 

,並試圖先拿到本週的緩存,如果它是一個高速緩存未命中,那麼你可以去endDate月份的最後日期和檢查本月緩存

Cache cache = cacheManager.getCache("08.06.2016_07.07.2016_exampleUser"); 

如果你找到了月份的緩存,你可以迭代從它得到星期的緩存,或者你必須從數據庫獲取星期的緩存。

+0

您能否提供一個示例,我如何聲明/注入自定義緩存管理器?現在我使用Spring Boot默認的緩存管理器自動配置 – Oleg

+0

您可以在'@ Service'類中執行'@ Autowired' CacheManager cacheManager – shazin