下面是一个使用流行的Java Ehcache系统的缓存示例。
首先,生成或获取Ehcache管理器配置文件。这个示例创建了一个具有堆外选项的缓存,并具有别名leadtools
:
的内容ehcache.xml
<配置
xmlns: xsi = " http://www.w3.org/2001/XMLSchema-instance "
xmlns = " http://www.ehcache.org/v3 "
xsi: schemaLocation = " http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd”>
<缓存别名= " leadtools ">
<键式>以</键式>
<值类型>java.io.Serializable</值类型>
<资源>
<堆单位= " m ">One hundred.</堆>
<offheap单位= " g ">1</ offheap>
</资源>
</缓存>
</配置>
接下来,将以下LEADTOOLS缓存配置XML文件添加到Document服务。这个XML文件引用了下面描述的实现ehCache的类,缓存管理器文件和别名:
的内容lead-ehcache.xml
<?xml version="1.0" encoding="utf-8"?>
<leadtools_cache>
<缓存>
<类型>com.yourapp.EhcacheObjectCache</类型>
<值>
<Value key="manager-config-file" Value ="ehcache.xml" />
<Value key="cache-alias" Value ="leadtools" /><——必须在上面的缓存管理器配置文件中定义——>
</值>
</缓存>
</ leadtools_cache>
替换里面的代码ServiceHelper。CreateCache
初始化Ehcache
对象,如示例所示:
// lead_ehcache_config.xml的路径
字符串config =“lead_ehcache_config.xml”;
试一试(FileInputStream fis =新FileInputStream(配置)){
试一试(LeadDynamicStream lds =新LeadDynamicStream (fis,真正的)) {
//创建
ObjectCache缓存= ObjectCache. createfromconfigurations (lds,零);
//使用它
ServiceHelper。_cache = cache;
}
}
最后,这是EhcacheObjectCache的实现:
包com.yourapp;
进口java.io.ByteArrayInputStream;
进口java.io.ByteArrayOutputStream;
进口java.io.File;
进口java.io.IOException;
进口java.io.ObjectInputStream;
进口java.io.ObjectOutputStream;
进口java.io.Serializable;
进口java.net.MalformedURLException;
进口java.net.URI;
进口java.net.URL;
进口java.util.EnumSet;
进口java.util.HashSet;
进口java.util.Iterator;
进口java.util.Map;
进口java.util.Set;
进口org.ehcache.Cache;
进口org.ehcache.CacheManager;
进口org.ehcache.config.builders.CacheManagerBuilder;
进口org.ehcache.xml.XmlConfiguration;
进口leadtools.InvalidOperationException;
进口leadtools.RasterException;
进口leadtools.caching.CacheItem;
进口leadtools.caching.CacheItemExpiredEvent;
进口leadtools.caching.CacheItemExpiringEvent;
进口leadtools.caching.CacheItemPolicy;
进口leadtools.caching.CacheSerializationMode;
进口leadtools.caching.CacheStatistics;
进口leadtools.caching.DefaultCacheCapabilities;
进口leadtools.caching.EnumerateCacheEntriesCallback;
进口leadtools.caching.ObjectCache;
/*
封装org.ehcache.Cache对象的leadtools. cache. objectcache的实现
1.创建或加载实例缓存。
2.创建一个EhcacheObjectCache实例来包装它
3.将它传递给需要CacheObject的LEADTOOLS文档工具包。例如,DocumentFactory。loadFromUrl或DocumentFactory.loadFromCache。然后一切
应该按预期工作
4.要从缓存中删除文档,请使用DocumentFactory.deleteFromCache
这个实现不支持每个项目的单独过期策略,因为Ehcache不支持。相反,它将使用这些政策
在传入的原始Ehcache对象中已经设置。
文档工具箱将调用ObjectCache的以下方法:
- getDefaultCacheCapabilities获取该缓存的支持类型。我们只支持获取/设置的最低要求(没有区域,外部url,磁盘
访问或自动序列化)。
—addOrGetExisting:通过以下参数向缓存中添加项:
项。regionName:将始终是文档ID (leadtools.documents.Document.getDocumentId)
项。keyName:该项的唯一标识,如page1_image或document_metadata。
实现使用regionName + "_" + keyName在缓存中创建唯一标识符,因为Ehcache不支持真分组。
项。Value:要存储的值,可以是:
—字节数组:对于原始文档数据和注释数据
字符串:在光栅编解码器选项,元数据等情况下。
—RasterImage和ISvgDocument对象:如果是DocumentCacheOptions。PAGE_IMAGE, PAGE_SVG, PAGE_SVG_BACK_IMAGE或PAGE_THUMBNAIL_IMAGE用于缓存图像。如果
如果发生这种情况,建议实现者从CacheEventListender中调用静态tryDispose方法,当项被删除,驱逐,过期或
更新。有关更多信息,请参阅示例代码。
—getCacheItem:从缓存中获取项目。参考上面的参数。
—remove:从缓存中删除项,并返回原值。
—deleteItem:快速删除缓存项。
—deleteAll:快速删除多个缓存项。从缓存中删除文档时调用
Document.setAutoDeleteFromCache(true)或DocumentFactory.deleteFromCache。
* /
公共类EhcacheObjectCache扩展ObjectCache {
//该类的配置选项
公共静态类{配置
//将来使用
}
//我们包装的Ehcache对象
私人缓存
公共缓存
缓存(){ 返回_cache;
}
// super.createFromConfigurations(iledstream)不需要参数构造函数
//该对象通过反射实例化
公共EhcacheObjectCache () {
超级();
}
公共EhcacheObjectCache(Cache
Cache) { 超级();
如果(缓存= =零){
扔新IllegalArgumentException (“缓存不能为空”);
}
init(缓存,零,零,零);
}
公共EhcacheObjectCache(Cache
Cache, EhcacheObjectCache。配置配置){ 超级();
如果(缓存= =零){
扔新IllegalArgumentException (“缓存不能为空”);
}
init(缓存,零,零、配置);
}
公共EhcacheObjectCache(String cacheManagerConfigFile, String cacheAlias) {
超级();
如果(cacheManagerConfigFile = =零|| cacheAlias ==零){
扔新IllegalArgumentException ("cacheManagerConfigFile和cacheAlias不能为空");
}
init (零, cacheManagerConfigFile, cacheAlias,零);
}
公共EhcacheObjectCache(String cacheManagerConfigFile, String cacheAlias, EhcacheObjectCache)配置配置){
超级();
如果(cacheManagerConfigFile = =零|| cacheAlias ==零){
扔新IllegalArgumentException ("cacheManagerConfigFile和cacheAlias不能为空");
}
init (零, cacheManagerConfigFile, cacheAlias, config);
}
公共无效init(Cache
Cache, String managerConfigFile, String cacheAlias, EhcacheObjectCache. init)配置配置){ 如果(缓存! =零){
这._cache = cache;
}
其他的{
Cache
createdCache = cacheFromManagerConfig(managerConfigFile, cacheAlias); 如果(createdCache ! =零){
init (createdCache,零,零、配置);
返回;
}
}
}
//用于解析区域和密钥对的辅助方法。文档将通过区域(文档ID,在缓存中不是唯一的)和键引用每个项
//(值本身,对于文档ID是唯一的)。Ehcache不支持这一点,因此只需将两个值连接起来以生成唯一的键
私人静态字符串resolveKey(字符串键,字符串区域){
如果(地区= =零|| region.length() == 0) {
//我们不支持
扔新UnsupportedOperationException(方式“必须提供缓存区域”);
}
返回地区+“_”+关键;
}
//未在此实现中使用
@Override
公共CacheItemExpiringEvent () {
返回零;
}
//未在此实现中使用
@Override
公共CacheItemExpiredEvent缓存过期(){
返回零;
}
@Override
公共字符串getName() {
返回“Ehcache ObjectCache”;
}
//我们只支持二进制序列化
@Override
公共getPolicySerializationMode() {
返回CacheSerializationMode.BINARY;
}
@Override
公共无效setPolicySerializationMode(CacheSerializationMode值){
//从不从文档工具箱中调用
}
@Override
公共CacheSerializationMode () {
返回CacheSerializationMode.BINARY;
}
@Override
公共无效setDataSerializationMode(CacheSerializationMode值){
//从不从文档工具箱中调用
}
@Override
公共布尔contains(String key, String regionName) {
如果(关键= =零)
扔新IllegalArgumentException ("键不能为空");
返回_cache。regionName containsKey (resolveKey(关键));
}
@Override
公共
T get(String key, Class> classOfT) { //从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共< T >无效set(String key, T值,Class> classOfT) {
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共无效enumeraterregions (EnumerateCacheEntriesCallback回调){
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共无效enumerateKeys(String region, EnumerateCacheEntriesCallback) {
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共Map
getValues(Iterator keys, String regionName) { //从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
私人静态布尔isAutoSerializable(类< ?> classOfT) {
String classOfTName = classOfT.getCanonicalName();
如果(classOfTName.equals (“java.lang.Long”) | |
classOfTName.equals (“java.lang.Integer”) | |
classOfTName.equals (“java.lang.Float”) | |
classOfTName.equals (“java.lang.Double”) | |
classOfTName.equals (“java.lang.Character”) | |
classOfTName.equals (“以”) | |
classOfTName.equals (“byte[]”))
返回真正的;
其他的
返回假;
}
私人< T >无效putValue(String resolvedKey, T值,类> classOfT)抛出IOException {
如果(! isAutoSerializable (classOfT)) {
试一试(ByteArrayOutputStream bos =新ByteArrayOutputStream ()) {
试一试(ObjectOutputStream out =新ObjectOutputStream (bos)) {
out.writeObject(价值);
字节[] data = bos.toByteArray();
_cache。把(resolvedKey、数据);
}
}
}其他的{
_cache。把(resolvedKey(序列化)值);
}
}
@SuppressWarnings (“不”)
私人
T getValue(String resolvedKey, Class> classOfT)抛出ClassNotFoundException, IOException { 如果(! isAutoSerializable (classOfT)) {
字节[]数据= (字节[]) _cache.get (resolvedKey);
如果(数据! =零){
试一试(ByteArrayInputStream bis =新ByteArrayInputStream(数据)){
试一试(ObjectInputStream in = .新ObjectInputStream (bis)) {
T值= (T)in.readObject();
返回价值;
}
}
}
}其他的{
对象值= _cache.get(resolvedKey);
如果(价值! =零){
返回(T)值;
}
}
返回零;
}
@Override
公共
CacheItem addOrGetExisting(CacheItem item, Class> classOfT, CacheItemPolicy policy) { 如果(项目= =零){
扔新IllegalArgumentException ("项目不能为空");
}
//获取唯一键
//获取当前项(如果存在)
//放置新项目
//返回旧的项目
//备注:policy未被使用
String resolvedKey = resolveKey(item.getKey(), item.getRegionName()));
CacheItem
oldItem =零; 如果(_cache.containsKey (resolvedKey)) {
试一试{
oldItem = getCacheItem(item.getKey(), classOfT, item.getRegionName());
}抓(例外ex) {
oldItem =零;
}
}
如果(item.getValue () = =零)
扔新RuntimeException ("CacheItem值不能为空");
试一试{
putValue(resolvedKey, item.getValue(), classOfT);
}抓(IOException e) {
扔RasterException.fromThrowable (e);
}
返回oldItem;
}
@Override
公共
CacheItem getCacheItem(String key, Class> classOfT, String regionName) { //获取唯一键
//获取项目
字符串resolveKey = resolveKey(key, regionName);
T值;
试一试{
value = getValue(resolvedKey, classOfT);
}抓(ClassNotFoundException | IOException e) {
扔RasterException.fromThrowable (e);
}
如果(价值! =零){
返回新CacheItem
(key, value, regionName); }
返回零;
}
@Override
公共(String key, Class)> classOfT, String regionName) {
//获取唯一键
//获取旧值
//删除项目
//返回旧值
T值=零;
字符串resolveKey = resolveKey(key, regionName);
如果(_cache.containsKey (resolvedKey)) {
试一试{
value = getValue(resolvedKey, classOfT);
}抓(ClassNotFoundException | IOException e) {
扔RasterException.fromThrowable (e);
}
_cache.remove (resolvedKey);
}
返回价值;
}
@Override
公共无效deleteItem(String key, String regionName) {
//获取唯一键
//删除项目
字符串resolveKey = resolveKey(key, regionName);
如果(_cache.containsKey (resolvedKey)) {
_cache.remove (resolvedKey);
}
}
@Override
公共长getCount(String regionName) {
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共EnumSet
getDefaultCacheCapabilities() { EnumSet
caps = EnumSet.of(DefaultCacheCapabilities. none); caps.add (DefaultCacheCapabilities.SERIALIZATION);
返回帽;
}
@Override
公共URI getItemVirtualDirectoryUrl(String key, String regionName) {
扔新UnsupportedOperationException(方式);
}
@Override
公共getStatistics(String keyName, String regionName) {
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共getStatistics() {
//从不从文档工具箱中调用
扔新UnsupportedOperationException(方式);
}
@Override
公共无效deleterregion (String regionName) {
扔新UnsupportedOperationException(方式"方法不支持。使用deleteAll”);
//每个文档实现一个缓存。如果不需要,请尝试从manage中删除_cache
}
@Override
公共URI getItemExternalResource(String key, String regionName)布尔读写){
///从不从文档工具箱中调用,因为我们不支持DefaultCacheCapabilities。EXTERNAL_RESOURCES
扔新UnsupportedOperationException(方式);
}
@Override
公共无效removeItemExternalResource(String key, String regionName) {
///从不从文档工具箱中调用,因为我们不支持DefaultCacheCapabilities。EXTERNAL_RESOURCES
扔新UnsupportedOperationException(方式);
}
@Override
公共URI beginaddexdexnalresource (String key, String regionName)布尔读写){
///从不从文档工具箱中调用,因为我们不支持DefaultCacheCapabilities。EXTERNAL_RESOURCES
扔新UnsupportedOperationException(方式);
}
@Override
公共< T >无效endAddExternalResource (布尔提交,字符串键,T值,类>类OfT, CacheItemPolicy policy, String regionName) {
///从不从文档工具箱中调用,因为我们不支持DefaultCacheCapabilities。EXTERNAL_RESOURCES
扔新UnsupportedOperationException(方式);
}
@Override
公共无效updatePolicy(String key, CacheItemPolicy policy, String regionName) {
//不支持此方法。在传递给构造函数的Cache对象上设置策略。
//从文档工具箱中调用。但我们可以放心地忽略它,而依赖于
//过期策略总是从外部设置在Ehcache对象中。
}
@Override
公共< T >布尔updateCacheItem(CacheItem
item, Class> classOfT) { //获取唯一键
//如果找到项目,更新它
//返回状态
String resolvedKey = resolveKey(item.getKey(), item.getRegionName()));
如果(_cache.containsKey (resolvedKey)) {
试一试{
putValue(resolvedKey, item.getValue(), classOfT);
}抓(IOException e) {
扔RasterException.fromThrowable (e);
}
返回真正的;
}其他的{
返回假;
}
}
@Override
公共无效deleteAll(String regionName, Set
key) { 如果(键= =零){
返回;
}
//删除所有键
//注意,文档工具箱将使用可能不存在的项的键调用该方法
//在缓存中,Ehcache没有问题,所以只是调用removeAll代替
//尝试遍历键来检查它们是否首先存在。
//当然,首先转换为我们的键格式
Set
resolvedKeys =新HashSet <字符串> (); 为(字符串键:键){
resolvedKeys。add (resolveKey(关键regionName));
}
_cache.removeAll (resolvedKeys);
}
私人Cache
cacheFromManagerConfig(String managerConfigFile, String cacheAlias) { 如果(managerConfigFile ! =零){
URL URL = Thread.currentThread().getContextClassLoader().getResource(managerConfigFile);
如果(url = =零){
//加载资源失败。尝试绝对路径。
文件configFile =新文件(managerConfigFile);
如果(configFile.exists ()) {
试一试{
url = configFile.toURI().toURL();
}
抓(MalformedURLException ex) {
扔新InvalidOperationException (“无法找到CacheManager配置文件”);
}
}
}
这.setManagerConfigFile (managerConfigFile);
XmlConfiguration xmlConfig =新XmlConfiguration (url);
_cacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
_cacheManager.init ();
如果(cacheAlias ! =零){
Cache
Cache = _cacheManager。getCache (cacheAlias字符串。类,可序列化的。类); 这.setCacheAlias (cacheAlias);
返回缓存;
}
其他的{
扔新InvalidOperationException ("Ehcache缓存别名不能为空");
}
}
其他的{
扔新InvalidOperationException ("Ehcache CacheManager配置文件不能为空");
}
}
@Override
受保护的无效loadConfigurationValues(映射<字符串,字符串>值){
超级.loadConfigurationValues(值);
字符串configFile = values.get(“manager-config-file”);
字符串cacheAlias = values.get(“cache-alias”);
如果(configFile = =零|| cacheAlias ==零){
扔新InvalidOperationException (“Ehcache缓存管理器配置文件和Ehcache缓存别名不能为空”);
}
EhcacheObjectCache。配置cfg =新EhcacheObjectCache.Configuration ();
Cache
Cache = cacheFromManagerConfig(configFile, cacheAlias); init(缓存,零,零cfg);
}
@Override
受保护的无效saveconfigationvalues (Map
values) {
超级.saveConfigurationValues(值);
如果(这.getManagerConfigFile () ! =零){
values.put (“manager-config-file”,这.getManagerConfigFile ());
}
如果(这.getCacheAlias () ! =零){
values.put (“cache-alias”,这.getCacheAlias ());
}
}
私人字符串_configFile;
//如果该对象是以Cache引用而不是
// a CacheManager配置文件
公共getManagerConfigFile() {
返回_configFile;
}
无效setManagerConfigFile(String configFile) {
这._configFile = configFile;
}
私人缓存管理器_cacheManager;
//如果该对象是以Cache引用而不是
// a CacheManager配置文件
公共CacheManager getManager() {
返回_cacheManager;
}
无效setManager(CacheManager manager) {
这._cacheManager = manager;
}
私人字符串_cacheAlias;
//如果该对象是以Cache引用而不是
// a CacheManager配置文件
公共字符串getCacheAlias() {
返回这._cacheAlias;
}
无效setCacheAlias(字符串cacheAlias) {
这._cacheAlias = cacheAlias;
}
}