ejb构建

在本文中,我将介绍如何使用单例EJB和Ehcache在Java EE中构建简单的参考数据缓存。 高速缓存将在给定的时间段后重置自身,并且可以通过调用REST端点或MBean方法“手动”清除。 这篇文章实际上是建立在以前的文章中如何建立和清除与单EJB和MBean的一个参考的数据高速缓存 ; 唯一的区别是,我将使用Ehcache缓存,而不是将数据存储在ConcurrentHashMap<String, Object> ,并且该缓存能够通过Ehcache方式进行更新。

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() –调用方法以完全清除缓存

实作

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

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Singleton
public class ReferenceDataCacheBean implements ReferenceDataCache {private static final String ALL_REFERENCE_DATA_KEY = "ALL_REFERENCE_DATA";private static final int CACHE_MINUTES_TO_LIVE = 100;private CacheManager cacheManager;private Cache refDataEHCache = null;   @EJBReferenceDataLogic referenceDataService;   @PostConstructpublic void initialize(){        cacheManager = CacheManager.getInstance();CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000);cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);refDataEHCache = new Cache(cacheConfiguration );cacheManager.addCache(refDataEHCache);}@Override@Lock(LockType.READ)public ReferenceData getReferenceData() {Element element = refDataEHCache.get(ALL_REFERENCE_DATA_KEY);if(element != null){    return (ReferenceData) element.getObjectValue();} else {ReferenceData referenceData = referenceDataLogic.getReferenceData();refDataEHCache.putIfAbsent(new Element(ALL_REFERENCE_DATA_KEY, referenceData));return referenceData;}      }@Overridepublic void evictAll() {cacheManager.clearAll();}    ...........
}

注意:

  • @Singleton –可能是此类中最重要的代码行。 此注释指定在应用程序中将仅存在一个这种类型的bean的单例。 该bean可以由多个线程同时调用。

现在让我们将代码分解为不同的部分:

缓存初始化

@PostConstruct注释用于在依赖项注入完成后需要执行的方法上,以执行任何初始化–在我们的情况下,是创建和初始化(eh)缓存。

缓存初始化

@PostConstructpublic void initialize(){       cacheManager = CacheManager.create();CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000);cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);refDataEHCache = new Cache(cacheConfiguration );cacheManager.addCache(refDataEHCache);}

注意:此注释只能注释一种方法。

Ehcache的所有用法都始于创建CacheManager ,它是Ehcache的容器,可维护其生命周期的各个方面。 我使用CacheManager.create()方法,这是一种使用默认配置创建单例CacheManager的工厂方法,如果存在,则将其返回:

cacheManager = CacheManager.create();

我通过提供缓存名称(“ referenceDataCache”)和内存中最大元素数( maxEntriesLocalHeap )来构建CacheConfiguration对象,然后将它们逐出(0 ==无限制),最后我进行设置自元素创建之日起,元素的默认生存时间:

CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000); cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);

现在,借助于CacheConfiguration对象,我以编程方式创建了我的参考数据缓存,并将其添加到CacheManager中。 请注意,只有将缓存添加到CacheManager后,它们才可用:

refDataEHCache = new Cache(cacheConfiguration ); cacheManager.addCache(refDataEHCache);

注意:您也可以以声明的方式创建缓存:创建CacheManager时,它将创建在配置中找到的缓存。 您可以通过指定配置文件的路径,类路径中的配置,InputStream中的配置或类路径中的默认ehcache.xml文件来创建CacheManager。 查看Ehcache代码示例以获取更多信息。

从缓存中获取数据

@Override
@Lock(LockType.READ)
public ReferenceData getReferenceData() {Element element = refDataEHCache.get(ALL_REFERENCE_DATA_KEY);if(element != null){    return (ReferenceData) element.getObjectValue();} else {ReferenceData referenceData = referenceDataLogic.getReferenceData();refDataEHCache.put(new Element(ALL_REFERENCE_DATA_KEY, referenceData));return referenceData;}
}

首先,我尝试根据元素的键从缓存中获取该元素,如果元素存在于缓存中( ==null ),则将从服务类接收该元素并将其放置在缓存中以供将来请求。

注意:

@Lock(LockType.READ)指定具有容器管理的并发性的单例bean的并发锁定类型。 设置为LockType.READ ,它将强制执行该方法以允许对其进行完全并发访问(假定未持有任何写锁)。 这正是我想要的,因为我只需要执行读取操作。 另一个更保守的选项@Lock(LockType.WRITE)顺便说一下是DEFAULT,它强制对bean实例的独占访问。 这应该在高度并发的环境中使方法变慢。

清除缓存

清除缓存

@Override public void evictAll() { cacheManager.clearAll(); }

CacheManager的clearAll()方法清除CacheManager中所有缓存的内容,但不删除任何缓存。 我在这里只是为了简单起见使用它,因为我只有一个缓存,因此需要刷新。

注意:如果您有多个高速缓存,即多个高速缓存名称,并且只想清除一个,则需要使用CacheManager.clearAllStartingWith(String prefix) ,该名称以CacheManager开头的名称清除CacheManager中所有高速缓存的内容。前缀,但不删除它们。

2.如何触发缓存缓存

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

MBean

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

接口

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

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

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

实作

CacheReset MxBean实现

@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批注导致在应用程序启动时由容器实例化Bean – 渴望初始化
  • 我再次使用@PostConstruct功能。 在这里, bean已在JMX中注册,如果有的话,请检查是否使用ObjectName将其删除。

休息服务电话

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

通过REST资源触发缓存刷新

@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(…)。

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

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

ejb构建

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

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

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

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

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

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

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

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

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

  5. python线程安全的单例_[python笔记] 单例的几种实现方式(线程安全)

    单例实现方式: 1.单例装饰器; 2.使用类: 3.使用元类 1.单例装饰器(非线程安全) 通过装饰器使一个类变成单例类,但是并非线程安全的,多线程状态下,每个线程创建不同的实例,因为没有加线程锁,所 ...

  6. java 单例 并发_完美的单例实现(The Perfect Singleton)

    原文链接  作者:Marek Piechut    译者:陈振阳 我经常遇到一些这样的Java程序员,他们不确定应该如何恰当的实现单例模式. 我不考虑在线程的环境中合适的实现.但是使用你能在网络上找到 ...

  7. 单例模式代码_设计模式之单例:程序员必知必会,举例子+代码示例,通俗易懂...

    推荐学习 给力!啃烂这套"核心知识"+"高级面试",成功定级腾讯JavaT4 举个通俗的例子:我们电脑桌面上的一些软件快捷方式,我们可以创建多个这样的快捷方式, ...

  8. angular 模块构建_我如何在Angular 4和Magento上构建人力资源门户

    angular 模块构建 Sometimes trying a new technology mashup works wonders. Both Magento 2 + Angular 4 are ...

  9. c# 多线程单例模式_单例模式,多线程单例,双重锁定单例,工场单例创建上下文...

    单例模式,多线程单例,双重锁定单例,工厂单例创建上下文. 单例子模式定义 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个 ...

最新文章

  1. 创建Silverlight自定义启动画面
  2. C# - 在foreach中删除元素
  3. startActivityForResult()
  4. ie浏览器 杂项样式错乱
  5. 45页的NAS神经网络搜索的综述,请查收!
  6. mysql怎样查询表的信息!
  7. virtualbox中安装ubuntu
  8. 在一个小写英文字母(a-z)组成的字符串的最短子串,其包含这个字符串中出现过的所有字母,输出最左边的该类子串
  9. php小白书,php小白的自学第一天
  10. 正则表达式 查找以某些字符开始 某些字符结束的匹配项 解决之道
  11. 在ECSHOP模板商品列表页 显示商品的评论等级和评论数量
  12. SpringMVC中的父子容器关系
  13. python最新版安装图集_[python] plist图集拆分小图
  14. 数学分析- 复旦 陈纪修 第一章(集合、映射与函数)
  15. Android SDK Platform Tools下载(包括adb 、 fastboot 和 systrace)
  16. 逆向-攻防世界-logmein
  17. 【读图】揭密大卖家们的钻展制作流程
  18. 两套工厂通用ERP系统【源代码免费分享】
  19. 01-贪吃蛇自动寻路
  20. QTextBrowser显示图片(图片文字对齐)

热门文章

  1. P3830-[SHOI2012]随机树【数学期望,dp】
  2. 2018/7/11-纪中某C组题【jzoj1293,jzoj1294,jzoj1295】
  3. 【DP】字串距离(luogu 1279)
  4. [XSY]Illyasviel的图游戏(博弈论)
  5. Java中如何实现线程的超时中断
  6. 扫盲,为什么分布式一定要有Redis?
  7. require.ensure与require AMD的区别
  8. JSP2.0中的表达式语言(EL表达式)
  9. 图解HashMap和HashSet的内部工作机制
  10. 阿里巴巴对Java编程【命名风格】的规约