javax.cache_新的Java缓存标准(javax.cache)

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管理器)保持同步,以及如何使用高速缓存来加快响应(通过@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 。

进一步阅读

要进一步阅读,请访问JSRs主页, 网址为https://github.com/jsr107/jsr107spec 。

参考: 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

javax.cache

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358673.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle修改某表中的顺序,oracle 数据库 , 表中字段顺序修改

1.首先需要sys或者system权限操作2.查询需要更改的表的IDselect object_id from all_objects where owner ‘用户名‘ and object_name ‘tableName‘; 注&#xff1a;表名需要大写3.通过ID查询出该表所有字段的顺序select obj# , col# , name from sys.col$ where obj# ‘…

clearfix清除浮动

在开发html页面时&#xff0c;我们经常会用到css的清除浮动&#xff0c;这里我推荐一种版本的清除方法&#xff0c;个人感觉非常好用。 .clearfix:before,.clearfix:after{content:"";display:table; } .clearfix:after{clear:both;} .clearfix{*zoom:1; } 1 <!DO…

fofa自动化爬虫脚本更新+详解

fofa自动化爬虫脚本更新详解 起因 最近要用到fofa爬虫&#xff0c;为什么要用爬虫不用api&#xff0c;问就是穷&#xff0c;想起来之前写过一个相关的脚本&#xff1a;Fofa-python-脚本&#xff0c;是很久以前写的了&#xff0c;之前写的时候有点问题&#xff0c;昨天重新修…

【APICloud系列|16】苹果开发者账号如何更改双重认证的手机号

按照一般的更改流程&#xff1a; 现在苹果账号安全系统升级&#xff0c;一般需要同意协议或者和本公司密切相关的人员才能操作。我这种借苹果手机操作的人除外。 那我用win7电脑如何操作呢&#xff1f; 登录苹果开发者账号&#xff0c; 进入如下管理账号地址&#xff1a;htt…

使用Hibernate JPA的自定义布尔用户类型

ANSI SQL 1999标准引入了BOOLEAN数据类型&#xff08;尽管遗憾的是仅作为可选功能&#xff09;。 但是到目前为止&#xff0c;大多数主要的数据库系统仍未实现它。 结果&#xff0c;布尔列以各种方式实现。 例如&#xff0c;包含“ Y”或“ N”的CHAR列&#xff0c;或使用BIT列…

JS文件信息收集工具-LinkFinder

0x00 前言 我们在渗透测试的之前&#xff0c;信息收集是必要的步骤&#xff0c;而JS文件中往往会暴露出很多的信息&#xff0c;比如一些注释的中铭感信息&#xff0c;内网ip地址泄露等等&#xff0c;还会有一些绝对路径或者相对路径的url&#xff0c;而这些url中很有可能就存在…

extjs中Store和grid的刷新问题

问题1&#xff1a;Store.load() 和Store.setproxy()区别 问题2:修改后的Grid 更新&#xff1a; Store.reload() 问题3&#xff0c;store删除后刷新会出问题 Store移除一行&#xff1a;Store.removeAt(Number index) 从数据集中删除指定索引位置的记录     或者Store.reload…

linux将txt文件复制为bak,Linux命令:cp (copy)复制文件或目录

复制文件&#xff0c;只有源文件较目的文件的修改时间新时&#xff0c;才复制文件cp -u -v file1 file2.将文件file1复制成文件file2cp file1 file2.采用交互方式将文件file1复制成文件file2cp -i file1 file2.将文件file1复制成file2&#xff0c;因为目的文件已经存在&#xf…

【APICloud系列|28】苹果开发者账号应该如何续费?

本次更新时间:2020/7/13 登录苹果开发者账号,一般还有1个月到期官方会给你发邮件,不懂英文的可以使用谷歌翻译功能。 目前的后台提醒是这样的,我给你翻译一下 这个如果没有到期,使用Apple Developer这个应用程序进行充值缴费。 对应地址:https://developer.apple.com/i…

linux中第一个进程的形成,Linux进程管理

1.进程基本概述定义&#xff1a;进程是已经启动的可执行程序的运行中实例。/proc目录下以数字为名的目录&#xff0c;每一个目录代表一个进程&#xff0c;保留着进程的属性信息&#xff0c;每一个进程的PID是唯一的&#xff0c;就算进程退出了&#xff0c;其他进程也不会占用其…

XX(北京)科技股份公司为啥需要购置服务器?

其实老板只是要一个量化的标准,只是没人能讲明白,我简单陈述一下: 公司现在只有一台阿里的1核两G的1M带宽服务器40G,属于低配,买了3年的,打了三折花了2800元左右,为啥需要额外购置服务器呢? 目前服务器上有,一个后台管理系统,一个小程序,一个APP,一个网站,目前就…

[BZOJ 1588] [HNOI 2002] 营业额统计

1588: [HNOI2002]营业额统计 Time Limit: 5 SecMemory Limit: 162 MBDescription 营业额统计 Tiger最近被公司升任为营业部经理&#xff0c;他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本&#xff0c;账本上记录了公司成立以…

Python----socket编程

socket 一、socket是什么&#xff1f; socket 通常也称为“套接字”&#xff0c;用于描述 IP 地址和端口&#xff0c;是一个通讯链的句柄。应用程序通常通过 “套接字”向网络发出请求或者应答网络请求。说白了&#xff0c;就是一种通讯机制。它类似于公司的电话客服部门&…

怎样编写测试类测试分支_测试技巧–不编写测试

怎样编写测试类测试分支对此没有太多疑问&#xff0c;测试代码的方式是一个有争议的问题。 不同的测试技术由于各种原因&#xff08;包括企业文化&#xff0c;经验和总体心理观点&#xff09;而受到不同开发人员的青睐。 例如&#xff0c;您可能更喜欢编写经典的单元测试&#…

linux文件权限umask,linux系统中UMASK权限的用法讲解

原标题&#xff1a;linux系统中UMASK权限的用法讲解umask一般是用在你初始创建一个目录或者文件的时候赋予他们的权限。这里要说明两点&#xff1a;1、针对目录来说x权限代表可以进入该目录&#xff0c;所以说对于这个权限初始赋值是没什么问题的;2、针对文件的x的权限代表执行…

怎么样才算高级java工程师

高级水平&#xff1a; 1.能对需求进行架构设计&#xff0c;选择框架以适应最合适的业务&#xff0c;作为某个项目的领导&#xff0c;带领团队完成项目。 2.有自己的开源项目&#xff0c;可以写出自己的组件&#xff0c;对开源的框架能够进行二次编写&#xff0c;java核心技术有…

Win32+API学习笔记:创建基本的窗口控件

创建一个标签 CreateWindowEx(0, "static", "姓名&#xff1a;", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 12, // xpos …

Autorize插件的使用方法

在Proxy或者Repeater有Request请求包后&#xff0c;要ctrlA全选&#xff0c;然后再右键发送到Autorize插件中&#xff1a; 如果只是像这样空白的发送是不会发送过去的&#xff1a;

粉丝提问:求问大神您会查exif吗?

无需下载安装任何软件,直接上传图片即可查看EXIF。支持JPEG、TIFF、CR2、NEF、XMP等多种图片格式破解Canon、

linux和windows的分区区别,Linux分区与Windows分区的区别

打开开始-管理工具-计算机管理&#xff0c;如下图所示&#xff1a;在Windows系统中&#xff0c;计算机的分区是用磁盘0&#xff0c;磁盘1&#xff0c;磁盘2&#xff0c;磁盘3来表示多块硬盘的&#xff0c;比如磁盘0表示第一块硬盘&#xff0c;磁盘2表示第二块硬盘&#xff0c;以…