一砌些、ehcahe的介紹
EhCache 是一個純Java的進程內(nèi)緩存框架,具有快速加匈、精干等特點寄症,是Hibernate中默認的CacheProvider。Ehcache是一種廣泛使用的開 源Java分布式緩存矩动。主要面向通用緩存,Java EE和輕量級容器。它具有內(nèi)存和磁盤存儲释漆,緩存加載器,緩存擴展悲没,緩存異常處理程序,一個gzip緩存servlet過濾器,支持REST和SOAP api等特點示姿。
優(yōu)點:?
1. 快速?
2. 簡單?
3. 多種緩存策略?
4. 緩存數(shù)據(jù)有兩級:內(nèi)存和磁盤甜橱,因此無需擔心容量問題?
5. 緩存數(shù)據(jù)會在虛擬機重啟的過程中寫入磁盤?
6. 可以通過RMI、可插入API等方式進行分布式緩存?
7. 具有緩存和緩存管理器的偵聽接口?
8. 支持多緩存管理器實例栈戳,以及一個實例的多個緩存區(qū)域?
9. 提供Hibernate的緩存實現(xiàn)
缺點:?
1. 使用磁盤Cache的時候非常占用磁盤空間:這是因為DiskCache的算法簡單岂傲,該算法簡單也導致Cache的效率非常高。它只是對元素直接追加存儲子檀。因此搜索元素的時候非常的快镊掖。如果使用DiskCache的,在很頻繁的應用中褂痰,很快磁盤會滿亩进。?
2. 不能保證數(shù)據(jù)的安全:當突然kill掉java的時候,可能會產(chǎn)生沖突缩歪,EhCache的解決方法是如果文件沖突了归薛,則重建cache。這對于Cache 數(shù)據(jù)需要保存的時候可能不利匪蝙。當然主籍,Cache只是簡單的加速,而不能保證數(shù)據(jù)的安全逛球。如果想保證數(shù)據(jù)的存儲安全千元,可以使用Bekeley DB Java Edition版本。這是個嵌入式數(shù)據(jù)庫需忿∽缏可以確保存儲安全和空間的利用率。
EhCache的分布式緩存有傳統(tǒng)的RMI屋厘,1.5版的JGroups涕烧,1.6版的JMS。分布式緩存主要解決集群環(huán)境中不同的服務器間的數(shù)據(jù)的同步問題汗洒。
下面將介紹SpringMVC+EhCache詳細實例议纯。
1、pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.maven.web</groupId>
<artifactId>springMVC</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springMVC Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<!-- ehcache 相關(guān)依賴 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<finalName>springMVC</finalName>
</build>
</project>
2溢谤、index.jsp 文件如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
? ? pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello page</title>
<script type="text/javascript" src="<%=basePath%>js/jquery.js" ></script>
</head>
<script>
function cunchu(){
? $.post("welcome/saveEcache", function(data) {
? alert("success");
? });
}
function huoqu(){
? ? $.post("welcome/getEcache", function(data) {
? alert(data);
? ? });
}
</script>
<body>
<div style="text-align: left;">
<input type="button" value="存儲數(shù)據(jù)" onclick="cunchu()">
<input type="button" value="獲取數(shù)據(jù)" onclick="huoqu()">
</div>
</body>
</html>
3瞻凤、mvc-dispatcher-servlet.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/context
? ? ? ? http://www.springframework.org/schema/context/spring-context-3.0.xsd
? ? ? ? http://www.springframework.org/schema/mvc
? ? http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
? ? ? ? http://www.springframework.org/schema/cache
? ? ? ? http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">
<!-- 說明:增加本段配置是為了解決增加<mvc:annotation-driven/>配置后的編碼問題,要放在<mvc:annotation-driven/>之前
等效 produces = "application/json; charset=utf-8" -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
? ? <cache:annotation-driven cache-manager="cacheManager" />?
<context:component-scan base-package="com.bufan.demo.controller" />
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
? ? <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">?
? ? ? ? <property name="cacheManager" ref="ehcache"></property>?
? ? </bean>?
? ? <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">?
? ? ? ? <property name="configLocation" value="/WEB-INF/ehcache-setting.xml"></property>?
? ? </bean>?
</beans>
4世杀、ehcache-setting.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!-- 指定一個文件目錄阀参,當EhCache把數(shù)據(jù)寫到硬盤上時,將把數(shù)據(jù)寫到這個文件目錄下 -->
<diskStore path="java.io.tmpdir"/>
<!-- 設(shè)定緩存的默認數(shù)據(jù)過期策略 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="10"
timeToLiveSeconds="20"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
<cache name="cacheTest1"
? ? ? ? maxElementsInMemory="1000"
? ? ? ? eternal="false"
? ? ? ? overflowToDisk="true"
? ? ? ? timeToIdleSeconds="100"
? ? ? ? timeToLiveSeconds="200"/>
? ? ?<cache name="cacheTest3"
? ? ? ? maxElementsInMemory="1000"
? ? ? ? eternal="false"
? ? ? ? overflowToDisk="true"
? ? ? ? timeToIdleSeconds="1000"
? ? ? ? timeToLiveSeconds="2000"/>
</ehcache>
這里我們配置了cacheTest策略瞻坝,1000秒過期蛛壳。
cache元素的屬性:
name:緩存名稱
maxElementsInMemory:內(nèi)存中最大緩存對象數(shù)
maxElementsOnDisk:硬盤中最大緩存對象數(shù),若是0表示無窮大
eternal:true表示對象永不過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性衙荐,默認為false
overflowToDisk:true表示當內(nèi)存緩存的對象數(shù)目達到了
maxElementsInMemory界限后捞挥,會把溢出的對象寫到硬盤緩存中。注意:如果緩存的對象要寫入到硬盤中的話忧吟,則該對象必須實現(xiàn)了Serializable接口才行砌函。
diskSpoolBufferSizeMB:磁盤緩存區(qū)大小,默認為30MB溜族。每個Cache都應該有自己的一個緩存區(qū)讹俊。
diskPersistent:是否緩存虛擬機重啟期數(shù)據(jù),是否持久化磁盤緩存,當這個屬性的值為true時,系統(tǒng)在初始化時會在磁盤中查找文件名 為cache名稱,后綴名為index的文件斩祭,這個文件中存放了已經(jīng)持久化在磁盤中的cache的index,找到后會把cache加載到內(nèi)存劣像,要想把 cache真正持久化到磁盤,寫程序時注意執(zhí)行net.sf.ehcache.Cache.put(Element element)后要調(diào)用flush()方法。
diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔摧玫,默認為120秒
timeToIdleSeconds: 設(shè)定允許對象處于空閑狀態(tài)的最長時間耳奕,以秒為單位。當對象自從最近一次被訪問后诬像,如果處于空閑狀態(tài)的時間超過了timeToIdleSeconds屬性 值屋群,這個對象就會過期,EHCache將把它從緩存中清空坏挠。只有當eternal屬性為false芍躏,該屬性才有效。如果該屬性值為0降狠,則表示對象可以無限 期地處于空閑狀態(tài)
timeToLiveSeconds:設(shè)定對象允許存在于緩存中的最長時間对竣,以秒為單位。當對象自從被存放到緩存中后榜配,如果處于緩存中的時間超過了 timeToLiveSeconds屬性值否纬,這個對象就會過期,EHCache將把它從緩存中清除蛋褥。只有當eternal屬性為false临燃,該屬性才有 效。如果該屬性值為0烙心,則表示對象可以無限期地存在于緩存中膜廊。timeToLiveSeconds必須大于timeToIdleSeconds屬性,才有 意義
memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時淫茵,Ehcache將會根據(jù)指定的策略去清理內(nèi)存爪瓜。可選策略有:LRU(最近最少使用匙瘪,默認策略)钥勋、FIFO(先進先出)炬转、LFU(最少訪問次數(shù))。
5算灸、HelloController 文件:
package com.bufan.demo.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
@Controller
@RequestMapping("/welcome")
public class HelloController {
@RequestMapping(value="rol",method=RequestMethod.GET)
public String printWelcome(ModelMap model){
model.addAttribute("message", "springMVC 例子");
SimpleDateFormat format=new SimpleDateFormat();
model.addAttribute("date",format.format(new Date()));
? ? return "hello";
}
@RequestMapping(value="saveEcache")
public void cunchu(ModelMap model,HttpServletResponse response) {
try {
PrintWriter out = response.getWriter();
Map<String, String> map=new HashMap<String, String>();
map.put("1", "test1");
map.put("2", "test2");
? ? ? ? Cache cache = LazySingleton.getInstance().getCache("cacheTest1");
? ? ? ? cache.put(new Element("param4", map));
? ? ? ? Element element2 = cache.get("param4");
? ? ? ? System.out.println("value====="+element2.getValue());//獲取緩存值
? ? ? ? out.print(model);
? ? out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@RequestMapping(value="getEcache")
public void huoqu(ModelMap model,HttpServletResponse response) {
? ? ? ? try {
PrintWriter out = response.getWriter();
Element element2 = LazySingleton.getInstance().getCache("cacheTest1").get("param4");
? ? System.out.println("value====="+element2.getValue());//獲取緩存值
? ? model.addAttribute("data",element2.getValue());
? ? out.print(model);
? ? out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6、LazySingleton
package com.bufan.demo.controller;
import net.sf.ehcache.CacheManager;
public class LazySingleton {
//私有靜態(tài)變量驻啤,加載時不初始化
? ? private static CacheManager lazySingleton = null;
? ? //私有的構(gòu)造方法菲驴,避免外部創(chuàng)建實例
? ? private LazySingleton(){
? ? }
? ? synchronized public static CacheManager getInstance(){
? ? ? if(lazySingleton == null){
? ? ? lazySingleton =? CacheManager.create();;
? ? ? }
? ? ? return lazySingleton;? ? ?
? ? }
}