如何使用单例EJB和MBean构建和清除参考数据缓存

在我的一个项目中,我需要使用EclipseLink作为ORM框架从Java EE 6 WebLogic环境中的多个源中加载参考数据。 由于我在Java EE世界中找不到与Spring YET的@Cacheable相当的注释,因此我不得不编写自己的缓存解决方案。 尽管参考数据几乎不会随时间变化,但一项额外的要求是能够从外部清除缓存。 所以就这样...

1.快取

这应该是只读缓存,可以从外部刷新它。 我希望将缓存作为服务的一种包装,为应用程序提供实际的参考数据–带代码的AOP样式!

接口

简单的缓存界面,用于参考数据

@Local
public interface ReferenceDataCache {/*** Returns all reference data required in the application */ReferenceData getReferenceData();/*** evict/flush all data from cache */void evictAll();
}

缓存功能定义了两种简单的方法:

  • getReferenceData() –缓存所有不同来源在后台收集的参考数据
  • evictAll() –调用方法以完全清除缓存

实作

使用@Singleton的简单参考数据缓存实现

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Singleton
public class ReferenceDataCacheBean implements ReferenceDataCache {private static final String ALL_REFERENCE_DATA_KEY = "ALL_REFERENCE_DATA";private ConcurrentHashMap<String, Object> refDataCache = null;@EJBReferenceDataService referenceDataService;@PostConstructpublic void initialize(){this.refDataCache = new ConcurrentHashMap<>(); }@Override@Lock(LockType.READ)public ReferenceData getReferenceData() {if(refDataCache.containsKey(ALL_REFERENCE_DATA_KEY)){			return refDataCache.get(ALL_REFERENCE_DATA_KEY);} else {ReferenceData referenceData = referenceDataService.getReferenceData();refDataCache.put(ALL_REFERENCE_DATA_KEY, referenceData);return referenceData;}		}@Overridepublic void evictAll() {refDataCache.clear(); 		}	..........
}

注意:

  • @Singleton –可能是此类中最重要的代码行。 此注释指定在应用程序中将仅存在一个这种类型的bean的单例。 该bean可以由多个线程同时调用。 它还带有@PostConstruct批注。 此注释用于需要依赖注入完成后才能执行任何初始化的方法,在本例中,该方法用于初始化“缓存”(哈希映射)
  • @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)声明单例会话bean的并发管理类型。 默认情况下,它设置为Container 。 我在这里使用它只是为了强调它的存在。 另一个选项ConcurrencyManagementType.BEAN指定Bean开发人员负责管理对Bean实例的并发访问。
  • 实际的“缓存”是ConcurrentHashMap ,它具有基于String的键并存储Object 。 由于bean的单例性质,它被保留在内存中
  • 注入的ReferenceDataService@Stateless @EJB ,它在后台收集来自不同来源的参考数据
  • getReferenceData()方法的实现非常简单–它检查ConcurrentHashMap是否具有将String键指定为常量“ ALL_REFERENCE_DATA ”的条目。 如果是这样,它将从内存中检索,否则将由服务Bean加载。
  • @Lock(LockType.READ)指定具有容器管理的并发性的单例bean的并发锁定类型。 当设置为LockType.READ ,它将强制执行该方法以允许对其进行完全并发访问(假定未持有任何写锁)。 这正是我想要的,因为我只需要执行读取操作。 另一个更保守的选项@Lock(LockType.WRITE)顺便说一下是DEFAULT,它强制对bean实例的独占访问。 这应该在高度并发的环境中使方法变慢。
  • evictAll()方法,只是从哈希图中删除所有元素。

2.刷新缓存

这篇文章的第二部分将讨论清除缓存的可能性。 由于缓存实现是企业Java Bean,因此我们可以从MBean或从Web服务中调用它。

MBean

如果您不熟悉Java管理扩展(JMX), 这是一种Java技术,它提供用于管理和监视应用程序,系统对象,设备(例如打印机)和面向服务的网络的工具。 这些资源由称为MBeans(用于Managed Bean)的对象表示 ,我强烈建议您从本教程的起点开始:Java管理扩展(JMX)

2.1.1。 接口

公开的方法仅允许通过JMX重置缓存:

CacheRest MBean

@MXBean
public interface CacheResetMXBean {void resetReferenceDataCache();	
}

“ MXBean是一种MBean,仅引用一组预定义的数据类型。 这样,您可以确保您的MBean可被任何客户端(包括远程客户端)使用,而无需客户端有权访问代表MBean类型的特定于模型的类。 MXBean提供了一种方便的方式将相关值捆绑在一起,而无需将客户端进行特殊配置以处理捆绑。” [4]

2.1.2。 实作

MBean的CacheReset实现

@Singleton
@Startup
public class CacheReset implements CacheResetMXBean {private MBeanServer platformMBeanServer;private ObjectName objectName = null;@EJBReferenceDataCache referenceDataCache;@PostConstructpublic void registerInJMX() {try {objectName = new ObjectName("org.codingpedia.simplecacheexample:type=CacheReset");platformMBeanServer = ManagementFactory.getPlatformMBeanServer();//unregister the mbean before registerting againSet<ObjectName> existing = platformMBeanServer.queryNames(objectName, null);if(existing.size() > 0){platformMBeanServer.unregisterMBean(objectName);}platformMBeanServer.registerMBean(this, objectName);} catch (Exception e) {throw new IllegalStateException("Problem during registration of Monitoring into JMX:" + e);}}	@Overridepublic void resetReferenceDataCache() {referenceDataCache.evictAll();}}

注意:

  • 如前所述,该实现仅调用上一节中介绍的注入的单例bean的evictAll()方法
  • 该bean也被定义为@Singleton
  • @Startup批注导致在应用程序启动时由容器实例化@Startup 渴望初始化
  • 我再次使用@PostConstruct功能。 在这里, bean已在JMX中注册,如果是,则检查是否使用ObjectName将其删除。

休息服务电话

我还内置了通过调用REST资源清除缓存的可能性。 在(rest-context)/ reference-data / flush-cache上执行HTTP POST时会发生这种情况:

在参考数据缓存上进行剩余调用

@Path("/reference-data")
public class ReferenceDataResource {@EJBReferenceDataCache referenceDataCache;@POST@Path("flush-cache")public Response flushReferenceDataCache() {referenceDataCache.evictAll();return Response.status(Status.OK).entity("Cache successfully flushed").build();}	@GET@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })public Response getReferenceData(@QueryParam("version") String version) {ReferenceData referenceData = referenceDataCache.getReferenceData();				if(version!=null && version.equals(referenceData.getVersion())){return Response.status(Status.NOT_MODIFIED).entity("Reference data was not modified").build();				} else {return Response.status(Status.OK).entity(referenceData).build();				}}	
}

注意@GET getReferenceData(...)方法中存在版本查询参数。 这表示参考数据上的哈希,如果尚未修改,则客户端将收到304未修改HTTP状态 。 这是节省一些带宽的好方法,尤其是在您拥有移动客户端的情况下。 有关REST服务设计和实现的详细讨论,请参阅我的教程“使用Jersey和Spring的Java REST API设计和实现”。

注意:

在集群环境中,当参考数据更改时,需要在部署了应用程序的每个JVM上调用resetCache(…)。

好吧,就是这样。 在本文中,我们学习了如何使用Java EE注释构建简单的缓存。 当然,您可以轻松扩展缓存功能,以提供对缓存对象的更精细的访问/清除。 在这种情况下,请不要忘记使用LockType.WRITE作为清除方法……

翻译自: https://www.javacodegeeks.com/2014/09/how-to-build-and-clear-a-reference-data-cache-with-singleton-ejbs-and-mbeans.html

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

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

相关文章

让 UV4 支持STC 单片机

Keil 本身并没有自带 STC 8051 单片机的数据&#xff0c;这样用起来就非常令人不爽&#xff0c;好在国内有个青年已经整理了一个补丁。 这个补丁包含三个修正&#xff1a; 汉字bug修正&#xff0c;这个是老生常谈了&#xff0c;很奇怪Keil十年来都没有修正这个&#xff0c;说明…

【总结】计算机网络常见问题

1、TCP/IP协议与OSI协议 相互通信的两个计算机系统必须高度协调工作才行&#xff0c;而这种“协调”是相当复杂的。 “分层”可将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题&#xff0c;而这些较小的局部问题就比较易于研究和处理。 计算机网络采用了分层的体系结构…

webpack3的CommonsChunkPlugin插件详解

webpack打出来的包在不做处理的情况下是非常大的&#xff0c;所有依赖都被塞进一个文件中&#xff0c;文件中有业务代码&#xff0c;有业务代码依赖的第三方库代码&#xff0c;还有webpack生成的运行时代码等。这样的一个文件不方便静态资源缓存&#xff0c;并且初始化页面的时…

详细介绍jQuery.outerWidth() 函数具体用法

outerWidth()函数用于设置或返回当前匹配元素的外宽度。外宽度默认包括元素的内边距(padding)、边框(border)&#xff0c;但不包括外边距(margin)部分的宽度。你也可以指定参数为true&#xff0c;以包括外边距(margin)部分的宽度。如下图&#xff1a; 如果你要获取其它情况的宽…

自动装箱

自Java 1.5起&#xff0c;所有Java开发人员都可以使用自动装箱功能。嗯&#xff0c;我可能太乐观了。 至少所有开发人员都应该可以使用自动装箱。 毕竟&#xff0c;在ORACLE页面上有一个很好的教程。 自动装箱是Java编译器在需要时自动从原始类型创建代码创建对象的代码时的现…

SQLite 入门教程(一)基本控制台(终端)命令

一、基本简介 SQLite 是一个自持的&#xff08;self-contained&#xff09;、无服务器的、零配置的、事务型的关系型数据库引擎。因为他很小&#xff0c;所以也可以作为嵌入式数据库内建在你的应用程序中。SQLite 被应用在 Solaris 10操作系统、Mac OS 操作系统、iPhone 和 Sky…

PHP中的session

1.1原理 1.session是服务器端的技术 2.session是基于cookie技术的 1.2session操作 1.默认情况下&#xff0c;会话不会自动开启&#xff0c;通过session_start()开启会话 2.通过session_id()获取会话的编号 3、通过$_SESSION操作会话 4、会话可以保存除了资源以外的所有类型…

Web前端开发css基础样式总结

颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255之间 一般都用16进制表示颜色 单位 1. px像素&#xff08;Pixel&#xff09;。像素,与分辨率…

nth-child(n)和nth-of-type(n)

:nth-child(n)&#xff1a;父元素的子元素的第n个 :nth-of-type(n)&#xff1a;父元素的 某类 子元素的第n个 注&#xff1a;n从0起&#xff0c;元素index从1起 nth-child(n)和nth-of-type(n)例&#xff1a; <head><style>body :nth-child(2) {height: 30px;ba…

Spring WebApplicationInitializer和ApplicationContextInitializer的混淆

我偶尔会混淆这两个概念-WebApplicationInitializer和ApplicationContextInitializer&#xff0c;并希望描述它们中的每一个&#xff0c;以便为我自己澄清它们。 我以前在这里写过有关WebApplicationInitializer的博客。 它仅在符合Servlet 3.0规范的Servlet容器中相关&#x…

Mysql修改binlog日志过期时间

1.临时生效 # 查看默认设置的过期时间 show variables like "%expire_logs%"; # 设置保留15天 set global expire_logs_days15 # 刷新日志 flush logs&#xff1b; #查看新生成的binlog日志 show master status\G: 注意&#xff1a;以上命令在数据库执行会立即生效&a…

提高CSS文件可维护性的五种方法

当完成一项前端的工作之后&#xff0c;许多人都会忘记该项目的结构与细节。然而代码并不是马上就能完全定型&#xff0c;在余下的时间里还有不断的维护工作&#xff0c;而这些工作也许不会是你自己完成。所以&#xff0c;结构优良的代码能很大程度上优化它的可维护性。下面列出…

什么是spring(转载)

spring是一个开源的java框架&#xff0c;集成了各种主流的技术包括web mvc&#xff0c;orm&#xff0c;ejb&#xff0c;rmi&#xff0c;javamail等 &#xff0c;他就象一个粘合济&#xff0c;在实际项目中&#xff0c;将前后台程序粘合在一起&#xff0c;构建出一个完整的系统。…

小程序小知识备忘

setData和React的setState一样是异步的吗&#xff1f; setData不是异步的&#xff0c;但是setData之后UI更新是异步的。因为逻辑层&#xff08;App Service&#xff09;和 视图层&#xff08;View&#xff09;是分开的。setData的第二个参数是UI更新后的回调。 组件中this.da…

记录您的里程和社区运行情况:Java EE 7真实体验

miles2run.org是跟踪跑步活动并与亲朋好友共享的简便方法。 可以创建然后跟踪基于天或基于距离的目标。 它还允许创建社区运行目标&#xff0c;并使多个跑步者参与并跟踪他们朝着该目标的活动。 您也可以找出本地跑步者并与他们联系。 该项目已开始&#xff0c;以帮助跟踪#Jav…

poj 1308 Is It A Tree?

// 题意: 给出一些边&#xff0c;由所给出的边能否构成一棵树.&#xff08;节点数<100&#xff09;// 思路: n个顶点的树具有3个特点:连通,不含环,恰好包含n-1条边.只要有任意两个,就能推导出第3个// 所以我们可以通过是否连通和不含环来判断可以构成树.// 不含环: 通过并查…

oracle在group by时某列有多个值的拼接

最近编码过程中出现了group by后&#xff0c;某些列会有多个值&#xff0c;而我需要把这些多个值的列进行拼接的情况&#xff0c;和大家分享一下。 有如下表student&#xff1a; 我们希望以class分组&#xff0c;每组的信息平铺&#xff0c;效果如下 分组首先想到的肯定是group…

自求

最近在写代码的时候发现了一个问题&#xff0c;总是在完成一个复杂的逻辑后不自信&#xff0c;不自信逻辑没有问题或者说没有其他问题。仔细注意这种感觉是怎么来的就会发现&#xff0c;在梳理完逻辑写代码的时候总也会出现一些小问题&#xff0c;这些小问题的出现和处理就是问…

在Spring中使用Asciidoctor:使用Spring MVC渲染Asciidoc文档

Asciidoc是一种基于文本的文档格式&#xff0c;因此如果要将文档提交到版本控制系统中并跟踪不同版本之间的更改&#xff0c;它非常有用。 这使Asciidoc成为编写书籍&#xff0c;技术文档&#xff0c;常见问题解答或用户手册的理想工具。 创建Asciidoc文档后&#xff0c;很可能…

移动端meta整理

<!doctype html><html><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1" /><!-- 默认使用最新浏览器 --><meta http-equiv"Cache-Control" content&qu…