- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解Spring整合Ehcache管理缓存由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
Ehcache 是一个成熟的缓存框架,你可以直接使用它来管理你的缓存.
Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现。它支持注解方式使用缓存,非常方便.
本文先通过Ehcache独立应用的范例来介绍它的基本使用方法,然后再介绍与Spring整合的方法.
概述 。
Ehcache是什么?
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。它是Hibernate中的默认缓存框架.
Ehcache已经发布了3.1版本。但是本文的讲解基于2.10.2版本.
为什么不使用最新版呢?因为Spring4还不能直接整合Ehcache 3.x。虽然可以通过JCache间接整合,Ehcache也支持JCache,但是个人觉得不是很方便.
安装 。
Ehcache 。
如果你的项目使用maven管理,添加以下依赖到你的pom.xml中.
1
2
3
4
5
6
|
<
dependency
>
<
groupId
>net.sf.ehcache</
groupId
>
<
artifactId
>ehcache</
artifactId
>
<
version
>2.10.2</
version
>
<
type
>pom</
type
>
</
dependency
>
|
如果你的项目不使用maven管理,请在 Ehcache官网下载地址 下载jar包.
Spring 。
如果你的项目使用maven管理,添加以下依赖到你的pom.xml中.
spring-context-support这个jar包中含有Spring对于缓存功能的抽象封装接口.
1
2
3
4
5
|
<
dependency
>
<
groupId
>org.springframework</
groupId
>
<
artifactId
>spring-context-support</
artifactId
>
<
version
>4.1.4.RELEASE</
version
>
</
dependency
>
|
Ehcache的使用 。
HelloWorld范例 。
接触一种技术最快最直接的途径总是一个Hello World例子,毕竟动手实践印象更深刻,不是吗?
(1) 在classpath下添加ehcache.xml 。
添加一个名为helloworld的缓存.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
ehcache
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation
=
"http://ehcache.org/ehcache.xsd"
>
<!-- 磁盘缓存位置 -->
<
diskStore
path
=
"java.io.tmpdir/ehcache"
/>
<!-- 默认缓存 -->
<
defaultCache
maxEntriesLocalHeap
=
"10000"
eternal
=
"false"
timeToIdleSeconds
=
"120"
timeToLiveSeconds
=
"120"
maxEntriesLocalDisk
=
"10000000"
diskExpiryThreadIntervalSeconds
=
"120"
memoryStoreEvictionPolicy
=
"LRU"
/>
<!-- helloworld缓存 -->
<
cache
name
=
"helloworld"
maxElementsInMemory
=
"1000"
eternal
=
"false"
timeToIdleSeconds
=
"5"
timeToLiveSeconds
=
"5"
overflowToDisk
=
"false"
memoryStoreEvictionPolicy
=
"LRU"
/>
</
ehcache
>
|
(2) EhcacheDemo.java 。
Ehcache会自动加载classpath根目录下名为ehcache.xml文件.
EhcacheDemo的工作步骤如下:
在EhcacheDemo中,我们引用ehcache.xml声明的名为helloworld的缓存来创建Cache对象; 。
然后我们用一个键值对来实例化Element对象; 。
将Element对象添加到Cache; 。
然后用Cache的get方法获取Element对象.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
class
EhcacheDemo {
public
static
void
main(String[] args)
throws
Exception {
// Create a cache manager
final
CacheManager cacheManager =
new
CacheManager();
// create the cache called "helloworld"
final
Cache cache = cacheManager.getCache(
"helloworld"
);
// create a key to map the data to
final
String key =
"greeting"
;
// Create a data element
final
Element putGreeting =
new
Element(key,
"Hello, World!"
);
// Put the element into the data store
cache.put(putGreeting);
// Retrieve the data element
final
Element getGreeting = cache.get(key);
// Print the value
System.out.println(getGreeting.getObjectValue());
}
}
|
输出 。
Hello, World.
Ehcache基本操作 。
Element、Cache、CacheManager是Ehcache最重要的API.
Element
,并被CacheManager
管理。它实现了对缓存的逻辑行为。Cache
的容器对象,并管理着Cache
的生命周期。创建CacheManager 。
下面的代码列举了创建CacheManager的五种方式.
使用静态方法create()会以默认配置来创建单例的CacheManager实例.
newInstance()方法是一个工厂方法,以默认配置创建一个新的CacheManager实例.
此外,newInstance()还有几个重载函数,分别可以通过传入String、URL、InputStream参数来加载配置文件,然后创建CacheManager实例.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// 使用Ehcache默认配置获取单例的CacheManager实例
CacheManager.create();
String[] cacheNames = CacheManager.getInstance().getCacheNames();
// 使用Ehcache默认配置新建一个CacheManager实例
CacheManager.newInstance();
String[] cacheNames = manager.getCacheNames();
// 使用不同的配置文件分别创建一个CacheManager实例
CacheManager manager1 = CacheManager.newInstance(
"src/config/ehcache1.xml"
);
CacheManager manager2 = CacheManager.newInstance(
"src/config/ehcache2.xml"
);
String[] cacheNamesForManager1 = manager1.getCacheNames();
String[] cacheNamesForManager2 = manager2.getCacheNames();
// 基于classpath下的配置文件创建CacheManager实例
URL url = getClass().getResource(
"/anotherconfigurationname.xml"
);
CacheManager manager = CacheManager.newInstance(url);
// 基于文件流得到配置文件,并创建CacheManager实例
InputStream fis =
new
FileInputStream(
new
File
(
"src/config/ehcache.xml"
).getAbsolutePath());
try
{
CacheManager manager = CacheManager.newInstance(fis);
}
finally
{
fis.close();
}
|
添加缓存 。
需要强调一点,Cache对象在用addCache方法添加到CacheManager之前,是无效的.
使用CacheManager的addCache方法可以根据缓存名将ehcache.xml中声明的cache添加到容器中;它也可以直接将Cache对象添加到缓存容器中.
Cache有多个构造函数,提供了不同方式去加载缓存的配置参数.
有时候,你可能需要使用API来动态的添加缓存,下面的例子就提供了这样的范例.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// 除了可以使用xml文件中配置的缓存,你也可以使用API动态增删缓存
// 添加缓存
manager.addCache(cacheName);
// 使用默认配置添加缓存
CacheManager singletonManager = CacheManager.create();
singletonManager.addCache(
"testCache"
);
Cache test = singletonManager.getCache(
"testCache"
);
// 使用自定义配置添加缓存,注意缓存未添加进CacheManager之前并不可用
CacheManager singletonManager = CacheManager.create();
Cache memoryOnlyCache =
new
Cache(
"testCache"
,
5000
,
false
,
false
,
5
,
2
);
singletonManager.addCache(memoryOnlyCache);
Cache test = singletonManager.getCache(
"testCache"
);
// 使用特定的配置添加缓存
CacheManager manager = CacheManager.create();
Cache testCache =
new
Cache(
new
CacheConfiguration(
"testCache"
, maxEntriesLocalHeap)
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
.eternal(
false
)
.timeToLiveSeconds(
60
)
.timeToIdleSeconds(
30
)
.diskExpiryThreadIntervalSeconds(
0
)
.persistence(
new
PersistenceConfiguration().strategy(Strategy.LOCALTEMPSWAP)));
manager.addCache(testCache);
|
删除缓存 。
删除缓存比较简单,你只需要将指定的缓存名传入removeCache方法即可.
1
2
|
CacheManager singletonManager = CacheManager.create();
singletonManager.removeCache(
"sampleCache1"
);
|
实现基本缓存操作 。
Cache最重要的两个方法就是put和get,分别用来添加Element和获取Element.
Cache还提供了一系列的get、set方法来设置或获取缓存参数,这里不一一列举,更多API操作可参考官方API开发手册.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
/**
* 测试:使用默认配置或使用指定配置来创建CacheManager
*
* @author victor zhang
*/
public
class
CacheOperationTest {
private
final
Logger log = LoggerFactory.getLogger(CacheOperationTest.
class
);
/**
* 使用Ehcache默认配置(classpath下的ehcache.xml)获取单例的CacheManager实例
*/
@Test
public
void
operation() {
CacheManager manager = CacheManager.newInstance(
"src/test/resources/ehcache/ehcache.xml"
);
// 获得Cache的引用
Cache cache = manager.getCache(
"userCache"
);
// 将一个Element添加到Cache
cache.put(
new
Element(
"key1"
,
"value1"
));
// 获取Element,Element类支持序列化,所以下面两种方法都可以用
Element element1 = cache.get(
"key1"
);
// 获取非序列化的值
log.debug(
"key:{}, value:{}"
, element1.getObjectKey(), element1.getObjectValue());
// 获取序列化的值
log.debug(
"key:{}, value:{}"
, element1.getKey(), element1.getValue());
// 更新Cache中的Element
cache.put(
new
Element(
"key1"
,
"value2"
));
Element element2 = cache.get(
"key1"
);
log.debug(
"key:{}, value:{}"
, element2.getObjectKey(), element2.getObjectValue());
// 获取Cache的元素数
log.debug(
"cache size:{}"
, cache.getSize());
// 获取MemoryStore的元素数
log.debug(
"MemoryStoreSize:{}"
, cache.getMemoryStoreSize());
// 获取DiskStore的元素数
log.debug(
"DiskStoreSize:{}"
, cache.getDiskStoreSize());
// 移除Element
cache.remove(
"key1"
);
log.debug(
"cache size:{}"
, cache.getSize());
// 关闭当前CacheManager对象
manager.shutdown();
// 关闭CacheManager单例实例
CacheManager.getInstance().shutdown();
}
}
|
缓存配置 。
Ehcache支持通过xml文件和API两种方式进行配置.
xml方式 。
Ehcache的CacheManager构造函数或工厂方法被调用时,会默认加载classpath下名为ehcache.xml的配置文件。如果加载失败,会加载Ehcache jar包中的ehcache-failsafe.xml文件,这个文件中含有简单的默认配置.
ehcache.xml配置参数说明:
ehcache.xml的一个范例 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
ehcache
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation
=
"http://ehcache.org/ehcache.xsd"
>
<!-- 磁盘缓存位置 -->
<
diskStore
path
=
"java.io.tmpdir/ehcache"
/>
<!-- 默认缓存 -->
<
defaultCache
maxEntriesLocalHeap
=
"10000"
eternal
=
"false"
timeToIdleSeconds
=
"120"
timeToLiveSeconds
=
"120"
maxEntriesLocalDisk
=
"10000000"
diskExpiryThreadIntervalSeconds
=
"120"
memoryStoreEvictionPolicy
=
"LRU"
>
<
persistence
strategy
=
"localTempSwap"
/>
</
defaultCache
>
<
cache
name
=
"userCache"
maxElementsInMemory
=
"1000"
eternal
=
"false"
timeToIdleSeconds
=
"3"
timeToLiveSeconds
=
"3"
maxEntriesLocalDisk
=
"10000000"
overflowToDisk
=
"false"
memoryStoreEvictionPolicy
=
"LRU"
/>
</
ehcache
>
|
API方式 。
xml配置的参数也可以直接通过编程方式来动态的进行配置(dynamicConfig没有设为false).
1
2
3
4
5
6
|
Cache cache = manager.getCache(
"sampleCache"
);
CacheConfiguration config = cache.getCacheConfiguration();
config.setTimeToIdleSeconds(
60
);
config.setTimeToLiveSeconds(
120
);
config.setmaxEntriesLocalHeap(
10000
);
config.setmaxEntriesLocalDisk(
1000000
);
|
也可以通过disableDynamicFeatures()方式关闭动态配置开关。配置以后你将无法再以编程方式配置参数.
1
2
|
Cache cache = manager.getCache(
"sampleCache"
);
cache.disableDynamicFeatures();
|
Spring整合Ehcache 。
Spring3.1开始添加了对缓存的支持。和事务功能的支持方式类似,缓存抽象允许底层使用不同的缓存解决方案来进行整合。 Spring4.1开始支持JSR-107注解.
注:我本人使用的Spring版本为4.1.4.RELEASE,目前Spring版本仅支持Ehcache2.5以上版本,但不支持Ehcache3.
绑定Ehcache 。
org.springframework.cache.ehcache.EhCacheManagerFactoryBean这个类的作用是加载Ehcache配置文件.
org.springframework.cache.ehcache.EhCacheCacheManager这个类的作用是支持net.sf.ehcache.CacheManager.
spring-ehcache.xml的配置 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache
=
"http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">
<
description
>ehcache缓存配置管理文件</
description
>
<
bean
id
=
"ehcache"
class
=
"org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
>
<
property
name
=
"configLocation"
value
=
"classpath:ehcache/ehcache.xml"
/>
</
bean
>
<
bean
id
=
"cacheManager"
class
=
"org.springframework.cache.ehcache.EhCacheCacheManager"
>
<
property
name
=
"cacheManager"
ref
=
"ehcache"
/>
</
bean
>
<!-- 启用缓存注解开关 -->
<
cache:annotation-driven
cache-manager
=
"cacheManager"
/>
</
beans
>
|
使用Spring的缓存注解 。
开启注解 。
Spring为缓存功能提供了注解功能,但是你必须启动注解.
你有两个选择:
(1) 在xml中声明 。
像上一节spring-ehcache.xml中的做法一样,使用<cache:annotation-driven/> 。
1
|
<
cache:annotation-driven
cache-manager
=
"cacheManager"
/>
|
(2) 使用标记注解 。
你也可以通过对一个类进行注解修饰的方式在这个类中使用缓存注解.
范例如下:
1
2
3
4
|
@Configuration
@EnableCaching
public
class
AppConfig {
}
|
注解基本使用方法 。
Spring对缓存的支持类似于对事务的支持.
首先使用注解标记方法,相当于定义了切点,然后使用Aop技术在这个方法的调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑.
下面三个注解都是方法级别:
@Cacheable 。
表明所修饰的方法是可以缓存的:当第一次调用这个方法时,它的结果会被缓存下来,在缓存的有效时间内,以后访问这个方法都直接返回缓存结果,不再执行方法中的代码段.
这个注解可以用condition属性来设置条件,如果不满足条件,就不使用缓存能力,直接执行方法.
可以使用key属性来指定key的生成规则.
@CachePut 。
与@Cacheable不同,@CachePut不仅会缓存方法的结果,还会执行方法的代码段.
它支持的属性和用法都与@Cacheable一致.
@CacheEvict 。
与@Cacheable功能相反,@CacheEvict表明所修饰的方法是用来删除失效或无用的缓存数据.
下面是@Cacheable、@CacheEvict和@CachePut基本使用方法的一个集中展示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
@Service
public
class
UserService {
// @Cacheable可以设置多个缓存,形式如:@Cacheable({"books", "isbns"})
@Cacheable
({
"users"
})
public
User findUser(User user) {
return
findUserInDB(user.getId());
}
@Cacheable
(value =
"users"
, condition =
"#user.getId() <= 2"
)
public
User findUserInLimit(User user) {
return
findUserInDB(user.getId());
}
@CachePut
(value =
"users"
, key =
"#user.getId()"
)
public
void
updateUser(User user) {
updateUserInDB(user);
}
@CacheEvict
(value =
"users"
)
public
void
removeUser(User user) {
removeUserInDB(user.getId());
}
@CacheEvict
(value =
"users"
, allEntries =
true
)
public
void
clear() {
removeAllInDB();
}
}
|
@Caching 。
如果需要使用同一个缓存注解(@Cacheable、@CacheEvict或@CachePut)多次修饰一个方法,就需要用到@Caching.
1
2
|
@Caching
(evict = {
@CacheEvict
(
"primary"
),
@CacheEvict
(cacheNames=
"secondary"
, key=
"#p0"
) })
public
Book importBooks(String deposit, Date date)
|
@CacheConfig 。
与前面的缓存注解不同,这是一个类级别的注解.
如果类的所有操作都是缓存操作,你可以使用@CacheConfig来指定类,省去一些配置.
1
2
3
4
5
|
@CacheConfig
(
"books"
)
public
class
BookRepositoryImpl
implements
BookRepository {
@Cacheable
public
Book findBook(ISBN isbn) {...}
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/jingmoxukong/p/5975994.html 。
最后此篇关于详解Spring整合Ehcache管理缓存的文章就讲到这里了,如果你想了解更多关于详解Spring整合Ehcache管理缓存的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我阅读了有关 JSR 107 缓存 (JCache) 的内容。 我很困惑:据我所知,每个 CPU 都管理其缓存内存(无需操作系统的任何帮助)。 那么,为什么我们需要 Java 缓存处理程序? (如果C
好吧,我是 jQuery 的新手。我一直在这里和那里搞乱一点点并习惯它。我终于明白了(它并不像某些人想象的那么难)。因此,鉴于此链接:http://jqueryui.com/sortable/#dis
我正在使用 Struts 2 和 Hibernate。我有一个简单的表,其中包含一个日期字段,用于存储有关何时发生特定操作的信息。这个日期值显示在我的 jsp 中。 我遇到的问题是hibernate更
我有点不确定这里发生了什么,但是我试图解释正在发生的事情,也许一旦我弄清楚我到底在问什么,就可能写一个更好的问题。 我刚刚安装了Varnish,对于我的请求时间来说似乎很棒。这是一个Magneto 2
解决 Project Euler 的问题后,我在论坛中发现了以下 Haskell 代码: fillRow115 minLength = cache where cache = ((map fill
我正试图找到一种方法来为我网络上的每台计算机缓存或存储某些 python 包。我看过以下解决方案: pypicache但它不再被积极开发,作者推荐 devpi,请参见此处:https://bitbuc
我想到的一个问题是可以从一开始就缓存网络套接字吗?在我的拓扑中,我在通过双 ISP 连接连接到互联网的 HAProxy 服务器后面有 2 个 Apache 服务器(带有 Google PageSpee
我很难说出不同缓存区域 (OS) 之间的区别。我想简要解释一下磁盘\缓冲区\交换\页面缓存。他们住在哪里?它们之间的主要区别是什么? 据我了解,页面缓存是主内存的一部分,用于存储从 I/O 设备获取的
1.题目 请你为最不经常使用(LFU)缓存算法设计并实现数据结构。 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 in
1.题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: ① LRUCache(int capacity) 以正整数作为容量 capacity
我想在访问该 View 时关闭某些页面的缓存。它适用于简单查询模型对象的页面。 好像什么时候 'django.middleware.cache.FetchFromCacheMiddleware', 启
documents为 ExePackage element state Cache属性的目的是 Whether to cache the package. The default is "yes".
我知道 docker 用图层存储每个图像。如果我在一台开发服务器上有多个用户,并且每个人都在运行相同的 Dockerfile,但将镜像存储为 user1_myapp . user2 将其存储为 use
在 Codeigniter 中没有出现缓存问题几年后,我发现了一个问题。我在其他地方看到过该问题,但没有适合我的解决方案。 例如,如果我在 View 中更改一些纯 html 文本并上传新文件并按 F5
我在 Janusgraph 文档中阅读了有关 Janusgraph Cache 的内容。关于事务缓存,我几乎没有怀疑。我在我的应用程序中使用嵌入式 janusgrah 服务器。 如果我只对例如进行读取
我想知道是否有来自终端的任何命令可以用来匹配 Android Studio 中执行文件>使缓存无效/重新启动的使用。 谢谢! 最佳答案 According to a JetBrains employe
我想制作一个 python 装饰器来内存函数。例如,如果 @memoization_decorator def add(a, b, negative=False): print "Com
我经常在 jQuery 事件处理程序中使用 $(this) 并且从不缓存它。如果我愿意的话 var $this = $(this); 并且将使用变量而不是构造函数,我的代码会获得任何显着的额外性能吗?
是的,我要说实话,我不知道varnish vcl,我可以解决一些基本问题,但是我不太清楚,这就是为什么我遇到问题了。 我正在尝试通过http请求设置缓存禁止,但是该请求不能通过DNS而是通过 Varn
在 WP 站点上加载约 4000 个并发用户时遇到此问题。 这是我的配置: F5 负载均衡器 ---> Varnish 4,8 核,32 Gb RAM ---> 9 个后端,4 个核,每个 16 RA
我是一名优秀的程序员,十分优秀!