新的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
新的Java缓存标准(javax.cache)相关推荐
- javax.cache_新的Java缓存标准(javax.cache)
javax.cache 这篇文章探讨了新的Java缓存标准:javax.cache. 它如何适应Java生态系统 该标准由JSR107开发,作者是共同规范负责人. JSR107包含在JSR342开发的 ...
- Java 缓存工具类 Cache
Java 缓存工具类 Cache 工具类定义 工具类定义 package com.demo.utils;import org.springframework.util.StringUtils;impo ...
- Java缓存Ehcache-Ehcache的Cache预热机制及代码实现(Cache Warming for multi-tier Caches)
Ehcache中Cache预热机制 Cache预热机制简介 Ehcache在程序启动的时候并不会立即去加载位于磁盘上的数据到内存,而是在数据被用到的时候去加载(lazy load).因此在cache启 ...
- java缓存Guava Cache用法介绍
一.背景 在日常开发中,有很多这种场合:有一些数据量不是很大,不会经常改动,并且访问非常频繁:但是,由于受限于硬盘IO的性能,或者远程网络等原因,获取可能非常耗时,导致我们的程序非常慢.这在某些业务上 ...
- Java缓存学习之五:spring 对缓存的支持
(注意标题,Spring对缓存的支持 这里不单单指Ehcache ) 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache ...
- 写缓存java,编写线程安全的Java缓存读写机制 (原创)
一种习以为常的缓存写法: IF value in cached THEN return value from cache ELSE compute value save value in cache ...
- 玩转Spring Cache --- 整合进程缓存之王Caffeine Cache和Ehcache3.x【享学Spring】
每篇一句 人到中年就是一部西游记:悟空的压力,八戒的身材,沙僧的发型,唐僧的唠叨 前言 前面文章大篇幅详细讲解了Spring Cache缓存抽象.三大缓存注解的工作原理等等.若是细心的小伙伴会发现:讲 ...
- java协议标准与规范
本栏目提供了大量的 Java 技术标准与规范的简介.官方网址以及 developerWorks 网站上相关的技术资源.通过本栏目,您不但可以了解当前 Java 社区主要的技术标准和规范,还可以通过查看 ...
- Oracle 11g新特性之缓存与连接池
Oracle 11g新特性之缓存与连接池 上一篇 /下一篇 2008-03-26 16:03:19 / 个人分类:Oracle 数据库 11g面向 DBA 和开发人员的重要新特性 查看( 414 ) ...
最新文章
- PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call
- 基础005_V7-Select IO
- sgu 207 Robbers
- OpenCv——merge()函数数据合并
- ___new__方法和__init__方法的区别
- 华为下调2020年印度市场收入目标,或裁员60%至70%
- python建筑工程中的应用_Python最佳工程实践,建立一个完美的工程项目
- unlocker207安装失败解决方法
- httpcore系列(一)初识httpcore
- 上课笔记-机器学习(5)-美国人口普查数据进行收入预测分类
- 我市“一卡通”被授予国家金卡工程优秀应用成果奖
- 黑鲨helo支持html吗,黑鲨游戏手机Helo发布 张大仙公布私人配置
- 安卓疫情打卡APP源码
- IP切换代理 免费资源共享
- 数字藏品平台金乌元宇助力中国数字文创发展
- 神经网络正则化java_聊聊神经网络中的正则化
- linux系统管理员基础
- 在uni-app中如何使用一键登录,如何使用手机号一键登录
- Vigenere密码加密解密原理
- 营销之外,太二由“酸菜鱼”变身“捞金鱼”还缺什么?
热门文章
- graal java_如何在CircleCI上构建支持Graal的JDK8?
- 通过OAuth 2.0和Okta使用安全的服务器到服务器通信构建Spring Boot应用
- 队列和消息队列_消息队列概述[幻灯片]
- hystrix熔断 简介_Hystrix简介– Hello World
- java使用泛型后消除泛型_如何以及何时使用泛型
- hystrix应用 博客_用Hystrix保护您的应用程序
- spring安全_Spring安全–幕后
- cassandra使用心得_使用Cassandra和Nutch爬网
- Fn函数来构建Oracle ADF应用程序
- Java的新视差控件(JavaFX)