新的Java緩存標準(javax.cache)

這篇文章探討了新的Java緩存標準:javax.cache。

它如何適應Java生態系統

該標準由JSR107開發,作者是共同規范負責人。 JSR107包含在JSR342開發的Java EE 7中。 Java EE 7將于2012年底完成。但是與此同時,javax.cache將在Java SE 6和更高版本以及Java EE 6環境以及Spring和其他流行環境中運行。

JSR107具有草稿狀態。 目前,我們的API版本為0.3,參考實現和TCK。 本文中的代碼示例對此版本適用。

采用

作為專家組的活躍成員或對實施規范感興趣的供應商是:

  • 兵馬俑– Ehcache
  • Oracle –一致性
  • JBoss – Infinispan
  • IBM – ExtemeScale
  • SpringSource – Gemfire
  • 電網增益
  • 最高溫度
  • Google App Engine Java

Terracotta將為Ehcache發布一個模塊,使其與最終草案一致,然后在最終版本需要時對其進行更新。

特征

從設計的角度來看,基本概念是CacheManager,用于保存和控制Cache的集合。 緩存具有條目。 基本的API可以像地圖一樣具有以下附加功能:

  • 原子操作,類似于java.util.ConcurrentMap
  • 直讀緩存
  • 直寫式緩存
  • 緩存事件監聽器
  • 統計
  • 交易,包括所有隔離級別
  • 緩存注釋
  • 具有定義的鍵和值類型的通用緩存
  • 按引用定義存儲(僅適用于堆緩存)和按值存儲

可選功能

我們沒有采用針對不同用戶群體(例如Java SE和Spring / EE)的規范,而是采用了不同的方法。

首先,對于Java SE樣式緩存,沒有依賴性。 對于可能要使用批注和/或事務的Spring / EE,這些框架將滿足相關性。

其次,我們通過ServiceProvider.isSupported(OptionalFeature功能)具有功能API,因此您可以在運行時確定實現的功能。 可選功能包括:

  • storeByReference-storeByValue是默認值
  • 交易性的
  • 注解

這使得實現有可能在不必支持所有功能的情況下支持規范,并允許最終用戶和框架發現功能是什么,以便他們可以動態配置適當的用法。

適用于獨立和分布式緩存

盡管該規范沒有規定特定的分布式緩存拓撲,但是可以意識到緩存很可能是分布式的。 我們有一個API涵蓋了這兩種用法,但它對分布式問題很敏感。 例如,CacheEntryListener具有偵聽事件的NotificationScope,因此可以將事件限制為本地傳遞。 我們沒有像keySet()和values()這樣的網絡成本高的映射方法。 而且,我們通常更喜歡零或低成本回報類型。 因此,雖然Map具有V put(K鍵,V值),但是javax.cache.Cache具有void put(K鍵,V值)。
類加載

緩存包含由多個線程共享的數據,這些線程本身可能正在一個JVM中的不同容器應用程序或OSGi捆綁軟件中運行,并且可能分布在集群中的多個JVM中。 這使類加載變得棘手。

我們已經解決了這個問題。 創建CacheManager時,可以指定類加載器。 如果未指定,則實現將提供默認值。 無論哪種方式,對象反序列化都將使用CacheManager的類加載器。

與使用后備方法的Ehcache這樣的緩存所采用的方法相比,這是一個很大的改進。 首先使用線程的上下文類加載器,然后失敗,然后嘗試另一個類加載器。 可以使它在大多數情況下都有效,但會遇到一些麻煩,并且因實現方式而有很大差異。

獲取代碼

該規范位于Maven中心。 Maven代碼段是:

<dependency><groupId>javax.cache</groupId><artifactId>cache-api</artifactId><version>0.3</version>
</dependency>

庫克API之旅

創建一個CacheManager

我們支持Java 6 java.util.ServiceLoader創建方法。 它將自動檢測您的類路徑中的緩存實現。 然后,使用以下命令創建一個CacheManager:

CacheManager cacheManager = Caching.getCacheManager();

它返回一個名為“ __default__”的單例CacheManager。 后續調用返回相同的CacheManager。

CacheManager可以在其中配置名稱和類加載器。

CacheManager cacheManager =Caching.getCacheManager("app1", Thread.currentThread().getContextClassLoader());

實現也可能支持直接創建新的功能,以實現最大的靈活性:

CacheManager cacheManager =new RICacheManager("app1", Thread.currentThread().getContextClassLoader());

或做同樣的事情而不在任何特定實現上增加編譯時間依賴項:

String className = "javax.cache.implementation.RIServiceProvider";
Class<ServiceProvider> clazz =(Class<ServiceProvider>)Class.forName(className);
ServiceProvider provider = clazz.newInstance();
return provider.createCacheManager(Thread.currentThread().getContextClassLoader(), "app1");

我們希望實現具有自己的知名配置文件,這些文件將用于配置CacheManager。 CacheManager的名稱可用于區分配置文件。 對于ehcache,這將是熟悉的ehcache.xml,它位于類路徑的根目錄,并帶有CacheManager名稱的連字符前綴。 因此,默認的CacheManager將僅是ehcache.xml,而“ myCacheManager”將是app1-ehcache.xml。

創建一個緩存

該API支持以編程方式創建緩存。 這補充了通常由聲明式配置緩存的約定,這些約定留給每個供應商。

以編程方式配置名為“ testCache”的緩存,該緩存設置為可讀取

cacheManager = getCacheManager();
CacheConfiguration cacheConfiguration = cacheManager.createCacheConfiguration();
cacheConfiguration.setReadThrough(true);
Cache testCache = cacheManager.createCacheBuilder("testCache").setCacheConfiguration(cacheConfiguration).build();

獲取對緩存的引用

您可以從CacheManager獲得緩存。 獲取名為“ testCache”的緩存:

Cache<Integer, Date> cache = cacheManager.getCache("testCache");

基本緩存操作

放入緩存:

Cache<Integer, Date> cache = cacheManager.getCache(cacheName);
Date value1 = new Date();
Integer key = 1;
cache.put(key, value1);

要從緩存中獲取:

Cache<Integer, Date> cache =cacheManager.getCache(cacheName);
Date value2 = cache.get(key);

要從緩存中刪除:

Cache<Integer, Date> cache =cacheManager.getCache(cacheName);
Integer key = 1;
cache.remove(key);

注解

JSR107引入了一組標準化的緩存注釋,它們對在依賴項注入容器中運行的帶注釋的類進行方法級別的緩存攔截。 緩存注釋正變得越來越流行,從Spring的Ehcache注釋開始,然后影響了Spring 3的緩存注釋。

JSR107批注涵蓋了最常見的緩存操作,包括:

  • @CacheResult –使用緩存
  • @CachePut –放入緩存
  • @CacheRemoveEntry –從緩存中刪除單個條目
  • @CacheRemoveAll –從緩存中刪除所有條目

當可以輸入所需的高速緩存名稱,鍵和值時,它們不是必需的。 有關詳細信息,請參見JavaDoc。 為了更好地控制,您可以指定所有這些以及更多。 在以下示例中,將cacheName屬性指定為“ domainCache”,將index指定為鍵,將domain指定為值。

public class DomainDao {@CachePut(cacheName="domainCache")public void updateDomain(String domainId, @CacheKeyParam int index,@CacheValue Domain domain) {...}
}

參考實現包括Spring和CDI的實現。 CDI是Java EE 6中引入的標準化容器驅動的注入。該實現已很好地模塊化以實現重用,并使用Apache許可證,因此,我們希望多個開源緩存可以重用它們。 盡管我們尚未完成Guice的實現,但這很容易做到。

注釋示例

此示例說明如何使用注釋使高速緩存與基礎數據結構(在本例中為Blog Manager)保持同步,以及如何使用高速緩存來加快響應(通過@CacheResult完成)

public class BlogManager {@CacheResult(cacheName="blogManager")public Blog getBlogEntry(String title) {...}@CacheRemoveEntry(cacheName="blogManager")public void removeBlogEntry(String title) {...}@CacheRemoveAll(cacheName="blogManager")public void removeAllBlogs() {...}@CachePut(cacheName="blogManager")public void createEntry(@CacheKeyParam String title, @CacheValue Blog blog) {...}@CacheResult(cacheName="blogManager")public Blog getEntryCached(String randomArg, @CacheKeyParam String title){...}}

接線彈簧

對于Spring,關鍵是以下配置行,該行將緩存注釋攔截器添加到Spring上下文中:

<jcache-spring:annotation-driven proxy-target-class="true"/>

一個完整的例子是:

<beans><context:annotation-config/><jcache-spring:annotation-driven proxy-target-class="true"/><bean id="cacheManager" factory-method="getCacheManager" />
</beans>

基于JSR107貢獻者Eric Dalquist的早期工作,Spring具有自己的緩存注釋。 這些注釋和JSR107將愉快地共存。

連接CDI

首先創建javax.cache.annotation.BeanProvider的實現,然后告訴CDI在/ META-INF / services /的類路徑中聲明一個名為javax.cache.annotation.BeanProvider的資源在哪里找到。

有關使用CDI的Weld實現的示例,請參見CDI測試工具中的CdiBeanProvider 。

進一步閱讀

要進一步閱讀,請訪問位于https://github.com/jsr107/jsr107spec的JSR主頁。

參考: javax.cache:我們的JCG合作伙伴 Greg Luck在Greg Luck的Blog上發布 的新Java緩存標準 。

相關文章 :
  • Spring 3.1緩存抽象教程
  • Java EE6 CDI,命名組件和限定符
  • JBoss 4.2.x Spring 3 JPA Hibernate教程
  • JBoss 4.2.x Spring 3 JPA Hibernate教程第2部分
  • Java教程和Android教程列表

翻譯自: https://www.javacodegeeks.com/2011/10/new-java-caching-standard-javaxcache.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374219.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374219.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374219.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Eclipse搭建scala環境(解決“JDT weaving is currently disabled”問題)

隨著Apache Spark&#xff0c;scala也成了必學的語言&#xff0c;下面講一下Eclipse搭建scala開發環境。 網上有很多的教程&#xff0c;但是給的scala的地址下載的插件無法開發scala&#xff0c;會出現“JDT weaving is currently disabled”的問題,這是由于使用了錯誤的Scala地…

python如何輸出結果_如何在python2.7中打印輸出結果?

我正在存儲一些數據&#xff0c;如溫度&#xff0c;濕度和強度&#xff0c;這是我的Arduino輸出和輸入為我的python2.7&#xff0c;我正在繪制圖表的數據。我也想將Arduino輸出存儲到文本文件中&#xff0c;但是我無法這樣做&#xff1a; 這是我的python代碼import serial impo…

python字符串連接的三種方法及其效率、適用場景詳解

python字符串連接的方法&#xff0c;一般有以下三種:方法1&#xff1a;直接通過加號()操作符連接website& 39;python& 39;& 39;tab& 39;& 39; com& 39;方法2 python字符串連接的方法&#xff0c;一般有以下三種: 方法1&#xff1a;直接通過加號()操作符…

算法—遞歸實現 C(m,n)

/* 遞歸實現 C(m,n) */#include "stdio.h" int m,n,s,a[20];int main() {int c(int k);s0; a[0]0;scanf("%d%d",&m,&n);printf("\nC(%d,%d)%d\n",m,n,c(1));}//組合遞歸函數C(k) int c(int k) {int i,j;if(k<n){for(ia[k-1]1;i<m…

九齊51單片機使用注意事項:不要用float

在使用ADC計算電壓值時用了float&#xff0c;NY8B072A堆棧直接炸了&#xff0c;用32機習慣了&#xff0c;一直想不通&#xff0c;查了手冊才知道。 手冊是&#xff1a;《NYC_NY8_UM_v1.5_SC.pdf》 鏈接&#xff1a;https://www.nyquest.com.tw/cn/support/download/Nyquest_SW…

有益的CountDownLatch和棘手的Java死鎖

您是否曾經使用過java.util.concurrent.CountDownLatch &#xff1f; 這是在兩個或多個線程之間實現同步的非常方便的類&#xff0c;在該類中&#xff0c;一個或多個線程可以等待&#xff0c;直到在其他線程中執行的一組操作完成為止&#xff08;請參閱javadoc和此文章 &#x…

算法—回溯法橋本分數式

/* 將1-9九個數不重復地賦給不同的9個元素 &#xff0c;實現形如a/bcd/eff/hi 的形式&#xff1a;例&#xff1a;1/265/784/39 1/325/967/84 &#xff08;注意&#xff1a;1/265/784/39 和5/781/264/39 只能算一種解&#xff09;求滿足條件的解共有多少個&#xff1f; */ #in…

codeforces 703B

題意&#xff1a;有n座城市&#xff0c;其中k座是省會城市&#xff0c;每個城市有對應的點權&#xff0c;城市1-2-3-...-n-1有一條路相連&#xff0c;省會城市與其他所有的城市相連&#xff0c;且每兩個城市間最多有一條路&#xff0c;每條路的邊權為路連接的兩座城市的點權乘積…

go 基準測試 找不到函數_基于Golang做測試

本文在實習期間完成并完善&#xff0c;無任何公司機密&#xff0c;僅做語言交流學習之用。持續更新。1.Golang的單元測試Go語言提供了豐富的單測功能。在Go中&#xff0c;我們通常認為函數是最小的可執行單元。本例中使用兩個簡單的函數&#xff1a;IsOdd和IsPalindrome來進行G…

九齊NY8B072A單片機使用筆記(三)模擬串口RX

因為這款單片機沒有硬件串口&#xff0c;所以需要我們自己做軟件模擬串口。 用PA3作為RX&#xff0c;因為PA3可以作為外部輸入中斷EXTI1。 本人首先用輪詢的方式查PA3是否從高電平跳變到低電平&#xff08;起始信號&#xff09;&#xff0c;但是因為還有別的業務邏輯&#xf…

Java RESTful API集成測試

這篇文章將重點介紹為RESTful API&#xff08;帶有JSON有效負載&#xff09;編寫Java集成測試的基本原理和機制。 目的是對技術進行介紹&#xff0c;并為基本正確性編寫一些測試。 這些示例將使用最新版本的GitHub REST API。 對于內部應用程序&#xff0c;這種測試通常將在持…

java警惕自增的陷阱

public class proposal{public static void main(String[] args) {int count0;for(int i0;i<10;i){countcount;}System.out.println(count);}}結果輸出&#xff1a;0/*步驟一&#xff1a;JMV吧count值&#xff08;其值是0&#xff09;拷貝到臨時變量區&#xff1b;步驟二:co…

[LindCode] Binary Tree Postorder Traversal

Binary Tree Postorder Traversal Given a binary tree, return the postorder traversal of its nodes values. Example Given binary tree {1,#,2,3}, 1\2/3return [3,2,1]. Challenge Can you do it without recursion? SOLUTION 1: recursion&#xff1a; 分治法解決之&am…

九齊NY8B072A單片機使用筆記(一)TIMER0定時器

先上代碼 //8bit count up , max 0xFF void Ny8b072a_Timer0_Init(void) {PCON1 C_TMR0_Dis; // Disable Timer0//1 * (255 - 5) 250usTMR0 5; // Load 0x00 to TMR0 (Initial Timer0 register)//16M 2T Div8 1usT0MD C_PS0_TMR0 | C_PS0_Div8 ; // Prescaler0 is assign…

python菜鳥教程split_Python split()方法

網頁地址解析&#xff1a; #codingutf-8 str"http://www.runoob.com/python/att-string-split.html" print("0:%s"%str.split("/")[-1]) print("1:%s"%str.split("/")[-2]) print("2:%s"%str.split("/"…

金山毒霸垃圾清理

金山毒霸-垃圾清理-單文件封裝,清潔潔癖的愛好&#xff01; 實話&#xff0c;金山的軟件確實不錯。展望金山可以在軟件行業&#xff0c;做出讓世界都使用的。為國人扛起一片天 下載地址&#xff1a; http://pan.baidu.com/s/1dFa7GdV轉載于:https://www.cnblogs.com/xiaochina/…

并發優化–減少鎖粒度

在高負載多線程應用程序中&#xff0c;性能非常重要。 開發人員必須意識到并發問題才能獲得更好的性能。 當我們需要并發時&#xff0c;我們通常擁有必須由兩個或更多線程共享的資源。 在這種情況下&#xff0c;我們有一個競爭條件 &#xff0c;其中只有一個線程&#xff08;在…

Java1.5增加了新特性:可變參數

/*Java 可變參數Java1.5增加了新特性&#xff1a;可變參數&#xff1a;適用于參數個數不確定&#xff0c;類型確定的情況&#xff0c;java把可變參數當做數組處理。注意&#xff1a;可變參數必須位于最后一項。當可變參數個數多余一個時&#xff0c;必將有一個不是最后一項&…

C語言代碼規范(十)花里胡哨代碼鑒賞

一、宏定義篇 1、作者的目的是防止GPIO口賦值超過1。但是有明顯自覺高人一等&#xff0c;瞧不起讀者的感覺。 uint8_t not_func(uint8_t sw) {return (sw?1:0); }#define LED1(sw) PA12not_func(sw)修改建議&#xff1a; #define LED1 PA12 #define LED_ON 0 #de…

python-break循環中斷

Python break語句&#xff0c;就像在C語言中&#xff0c;打破了最小封閉for或while循環。 break語句用來終止循環語句&#xff0c;即循環條件沒有False條件或者序列還沒被完全遞歸完&#xff0c;也會停止執行循環語句。 break語句用在while和for循環中。 如果您使用嵌套循環&am…