新的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.mzph.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…