在我的一个项目中,我需要使用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

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

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

    ejb构建 在我的一个项目中,我需要使用EclipseLink作为ORM框架从Java EE 6 WebLogic环境中的多个源中加载参考数据. 由于我在Java EE世界中找不到与Spring YE ...

  2. ejb构建_如何使用单例EJB,Ehcache和MBean构建和清除参考数据缓存

    ejb构建 在本文中,我将介绍如何使用单例EJB和Ehcache在Java EE中构建简单的参考数据缓存. 高速缓存将在给定的时间段后重置自身,并且可以通过调用REST端点或MBean方法" ...

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

    在本文中,我将介绍如何使用单例EJB和Ehcache在Java EE中构建简单的参考数据缓存. 高速缓存将在给定的时间段后重置自身,并且可以通过调用REST端点或MBean方法"手动&quo ...

  4. 五种常用设计模式的python实现:单例、工厂、构建者、代理、观察模式

    这里写自定义目录标题 前言 1.单例模式 第 1 种,重写 __new__ 方法 第 2 种,闭包定义装饰器 2.工厂模式 第 1 种,简单工厂 第 2 种,工厂方法 第 3 种,抽象工厂 3.构建者 ...

  5. 大叔手记(10):别再让面试官问你单例

    大叔手记(10):别再让面试官问你单例(暨6种实现方式让你堵住面试官的嘴) ... 2012-2-19 09:03| 发布者: benben| 查看: 283| 评论: 0 摘要: 引子经常从Recr ...

  6. java单例实例对象在springboot中实例化了2次,原因竟然是热部署的锅(记一次神奇的bug)

    找bug的一天 神奇的bug spring中的单例 场景 代码 产生的问题 分析 进一步分析 解决问题 参考链接 说明 神奇的bug 前言:我写的明明是单例,可是为什么初始化了二次? 今天写的这个bu ...

  7. java本地定时缓存,单例可执行外部接口

    环境: 有些对外提供的工具模块不是很好引用reids依赖,需要使用本地缓存,本来行想省事直接使用hutool的超时缓存-TimedCache,但是这个工具是真的坑逼,到时间调用get方法还是能获取到数 ...

  8. 【EventBus】EventBus 源码解析 ( EventBus 构建 | EventBus 单例获取 | EventBus 构造函数 | EventBus 构建者 )

    文章目录 一.EventBus 单例获取 二.EventBus 构造函数 三.EventBus 构建者 一.EventBus 单例获取 在 EventBus 中 , 不论是进行注册 , 取消注册 , ...

  9. Spring工作原理与单例ThreadLocal

    最近看到spring管理的bean为单例的,当它与web容器整合的时候始终搞不太清除,就网上搜索写资料, Tomcat与多线程 servlet是多线程执行的,多线程是容器提供的能力. servlet为 ...

最新文章

  1. Github如何删除repository(仓库)
  2. labview实现字符串转16进制
  3. Django整理(二) - 视图和模板的初步使用
  4. Rancher添加主机docker命令
  5. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】答案
  6. 向xxxhub发了一个数据包,发现了···
  7. Windows 8 开发31日-第04日-新控件
  8. HDU - 4757 Tree(LCA+可持久化trie树)
  9. ArrayList和CopyOnWriteArrayList
  10. ubuntu上如何安装mysql
  11. 时间开关的工作原理、安装方法及其应用特点
  12. java五子棋技术路线,一位老码农的编程简史
  13. 安装 win7虚拟机
  14. cfd-post 流线很少
  15. 一文全搞定:应届生offer,三方,劳动合同区别与注意事项
  16. 计算机不识别lacie硬盘,windows10系统下移动硬盘读不出来的三种解决方案
  17. CSU2020期中测试模拟题1 问题 B: 小帅要缴税
  18. HRSC2016舰船检测训练实验过程记录
  19. 不同dom的blur事件和click事件发生冲突
  20. 普通本科到清华大学研究生的真实人生蜕变,看了保证你考研至少增加 50 分!青春值得你去拼搏!!

热门文章

  1. android解决工具类中没有context中的问题
  2. JAVA List集合转Page(分页对象) java 分页 PageModel 测试类TestPagerModel
  3. 服务器io修改,更改 Linux I/O 调度器来改善服务器性能
  4. html5页面转场,基于HTML5 SVG的页面过渡切换效果
  5. wireshark tcp抓包分析_网络分析系列之八_使用Wireshark抓包
  6. js 时间戳转换成时间_JavaScript 时间戳转成日期格式
  7. java反射机制+继承设计技巧
  8. volatile关键字的作用
  9. HDU2049(错列排序)
  10. java中list去除空值_Java –从列表中删除所有空值