ehcache

参考链接:https://blog.csdn.net/vbirdbest/article/details/72763048

ehcache与redis比较

  • ehcache通常和redis一块使用
  • ehcache直接在jvm虚拟机中缓存,速度快,效率高;但是缓存共享麻烦,集群分布式应用不方便。
  • redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多, 处理集群和分布式缓存方便,有成熟的方案。如果是单个应用或者对缓存访问要求很高的应用,用ehcache。如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。

Demo

1.pom.xml

1
2
3
4
5
<!--EhCache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>

2.增加配置,可以再resource文件夹下增加

默认情况下Ehcache会自动加载classpath根目录下名为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>

<!-- helloworld缓存 -->
<cache name="HelloWorldCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="5"
timeToLiveSeconds="5"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>

也可以直接写在文件里,Ehcacheconfig.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class EhCacheConfig{

@Bean(name = "ehCacheManager")
public static CacheManager cacheManager(){
CacheConfiguration cacheConfig = new CacheConfiguration();
cacheConfig.setName("course");
cacheConfig.setMemoryStoreEvictionPolicy("LRU");
cacheConfig.setMaxEntriesLocalHeap(1000);
cacheConfig.setEternal(true);
net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
config.addCache(cacheConfig);
CacheManager cacheManager = CacheManager.newInstance(config);
return cacheManager;
}
}

3.这里对cache做简单的封装:

先对Cache api做下了解,

方法 解释
add(request) 添加一个请求到缓存
addAll(List requesets) 添加一系列请求到缓存
delete(request,[oprions]) options可选择如何处理匹配的缓存,有ignoreSearch、ignoreMethod、ignoreVary
keys(request,[options]) 参数和delete一样,该方法返回一个Promise,即一个Cache键的数组
match(request,[options]) request为想要在cache中查找的Promise对象
matchAll(List requests,[options]) 同上
put(request,response) 允许将键值对存到当前缓存

工具类-EhCacheService

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@Component
public class EhCacheService {
//创建缓存管理器
private static CacheManager cacheManager = EhCacheConfig.cacheManager();
//缓存对象
private Cache cache;

public EhCacheService(){
this.cache = cacheManager.getCache("course");
}

/**
* @Description 获取 ehCache value
* @param key
*/
public Object getCache(String key) throws Exception{
//获取cache中的元素
Element element = cache.get(key);
if(element == null){
return null;
}
Object object = element.getObjectValue();
//转成jsonObject,json->value,result->key&value(json)
JSONObject result = new JSONObject();
JSONObject json = null;
if(object != null){
json = JSONObject.parseObject(object.toString());
result.put(Contants.TYPE,key);
result.put(Contants.DATA,json);
}
return result;
}

/**
* @Description 添加 chCache
* @param data
*/
public void addCache(String key,String data) throws Exception{
Element element = new Element(key,data);
cache.put(element);
}

/**
* @Description 获取cache中所有的value
*/
public List<Object> getCacheAll() throws Exception{
List<Object> list = new ArrayList<Object>();
List<String> keys = cache.getKeys();
Map<Object, Element> elements = cache.getAll(keys);
for (String key: keys) {
Element element = elements.get(key);
JSONObject result = new JSONObject();
if(element != null){
Object object = element.getObjectValue();
if(object != null){
JSONObject json = JSONObject.parseObject(object.toString());
result.put(Contants.TYPE,key);
result.put(Contants.DATA,json);
list.add(result);
}
}
}
return list;
}

/**
* @Description 删除缓存
* @param key
*/
public boolean removeCache(String key) throws Exception{
return cache.remove(key);
}

/**
* @Description 批量添加缓存
* @param elements
*/
public void addCacheList(List<Element> elements){
cache.putAll(elements);
}
}

使用:

这里拿一个现成的redisConsumer的例子来使用ehcache

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
/**
* activemq 消费者
*/
@Component
public class ActiveMqConsumer {

Logger logger = LoggerFactory.getLogger(ActiveMqConsumer.class);

@Autowired
private EhCacheService ehCacheService;

//Sub
@JmsListener(destination = "${activemq.topic}" , containerFactory = "topicListenerFactory")
public void subscribe(TextMessage text){
try {
logger.info("subscribe : "+ text.getText());
if(text != null){
//只获取其中的type、data和操作符command
JSONObject json = JSONObject.parseObject(text.getText());
String key = json.getString(Contants.TYPE);
String data = json.getString(Contants.DATA);
String command = json.getString(Contants.COMMAND);
switch (command){
case Contants.ADD:
//将消息数据存入ehcache
ehCacheService.addCache(key,data);
break;
case Contants.UPDATE:
ehCacheService.addCache(key,data);
break;
case Contants.DELETE:
ehCacheService.removeCache(key);
break;
default:
logger.info("method is not found ..... command:"+command);
}
}
} catch (Exception e) {
logger.error("JSM订阅解析异常! :",e.getMessage());
}
}
}