1、核心代碼<br><br>
package
com.XX.cache.ehcache;
import
java.lang.reflect.Method;
import
java.util.List;
import
net.sf.ehcache.Cache;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
import
org.springframework.aop.AfterReturningAdvice;
import
org.springframework.beans.factory.InitializingBean;
import
org.springframework.util.Assert;
/**
*
* 使用spring的ehcahe
* 做用是在用戶進行create/update/delete操做時來刷新/remove相關cache內容,這個攔截器實現了AfterReturningAdvice接口,將會在所攔截的方法執行後執行在public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)方法中所預約的操做
* @author fangj
* 2013-08-14
*
*/
public
class
MethodCacheAfterAdvice
implements
AfterReturningAdvice, InitializingBean
{
private
static
final
Log logger = LogFactory.getLog(MethodCacheAfterAdvice.
class
);
private
Cache cache;
public
void
setCache(Cache cache) {
this
.cache = cache;
}
public
MethodCacheAfterAdvice() {
super
();
}
public
void
afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)
throws
Throwable {
String className = arg3.getClass().getName();
List list = cache.getKeys();
for
(
int
i =
0
;i<list.size();i++){
String cacheKey = String.valueOf(list.get(i));
if
(cacheKey.startsWith(className)){
cache.remove(cacheKey);
logger.debug(
"remove cache "
+ cacheKey);
}
}
}
public
void
afterPropertiesSet()
throws
Exception {
Assert.notNull(cache,
"Need a cache. Please use setCache(Cache) create it."
);
}
}
|
package
com.XX.cache.ehcache;
import
java.io.Serializable;
import
net.sf.ehcache.Cache;
import
net.sf.ehcache.Element;
import
org.aopalliance.intercept.MethodInterceptor;
import
org.aopalliance.intercept.MethodInvocation;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
import
org.springframework.beans.factory.InitializingBean;
import
org.springframework.util.Assert;
/**
* 建立一個實現了MethodInterceptor接口的攔截器,用來攔截Service/DAO的方法調用,攔截到方法後,搜索該方法的結果在cache中是否存在,若是存在,返回cache中的緩存結果,若是不存在,返回查詢數據庫的結果,並將結果緩存到cache中
* @author fangj
* 2013-08-13
*/
public
class
MethodCacheInterceptor
implements
MethodInterceptor, InitializingBean
{
private
static
final
Log logger = LogFactory.getLog(MethodCacheInterceptor.
class
);
private
Cache cache;
public
void
setCache(Cache cache) {
this
.cache = cache;
}
public
MethodCacheInterceptor() {
super
();
}
/**
* 攔截Service/DAO的方法,並查找該結果是否存在,若是存在就返回cache中的值,
* 不然,返回數據庫查詢結果,並將查詢結果放入cache
*/
public
Object invoke(MethodInvocation invocation)
throws
Throwable {
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
Object result;
logger.debug(
"Find object from cache is "
+ cache.getName());
String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = cache.get(cacheKey);
if
(element ==
null
) {
logger.debug(
"Hold up method , Get method result and create cache........!"
);
result = invocation.proceed();
element =
new
Element(cacheKey, (Serializable) result);
cache.put(element);
}
return
element.getValue();
}
/**
* 得到cache key的方法,cache key是Cache中一個Element的惟一標識
* cache key包括 包名+類名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser
*/
private
String getCacheKey(String targetName, String methodName, Object[] arguments) {
StringBuffer sb =
new
StringBuffer();
sb.append(targetName).append(
"."
).append(methodName);
if
((arguments !=
null
) && (arguments.length !=
0
)) {
for
(
int
i =
0
; i < arguments.length; i++) {
sb.append(
"."
).append(arguments[i]);
}
}
return
sb.toString();
}
/**
* implement InitializingBean,檢查cache是否爲空
*/
public
void
afterPropertiesSet()
throws
Exception {
Assert.notNull(cache,
"Need a cache. Please use setCache(Cache) create it."
);
}
}
|
2、ehcahe配置文件html
一、src目錄下增長cacheContext.xml配置文件,內容以下java
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd"
>
<beans>
<!-- 引用ehCache的配置 -->
<bean id=
"defaultCacheManager"
class
=
"org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
>
<property name=
"configLocation"
>
<value>classpath:ehcache.xml</value>
</property>
</bean>
<!-- 定義ehCache的工廠,並設置所使用的Cache name -->
<bean id=
"ehCache"
class
=
"org.springframework.cache.ehcache.EhCacheFactoryBean"
>
<property name=
"cacheManager"
>
<ref local=
"defaultCacheManager"
/>
</property>
<property name=
"cacheName"
>
<value>DEFAULT_CACHE</value>
</property>
</bean>
<!-- find/create cache攔截器 -->
<bean id=
"methodCacheInterceptor"
class
=
"com.XX.cache.ehcache.MethodCacheInterceptor"
>
<property name=
"cache"
>
<ref local=
"ehCache"
/>
</property>
</bean>
<!-- flush cache攔截器 -->
<bean id=
"methodCacheAfterAdvice"
class
=
"com.XX.cache.ehcache.MethodCacheAfterAdvice"
>
<property name=
"cache"
>
<ref local=
"ehCache"
/>
</property>
</bean>
<!-- 觸發從緩存讀取數據的方法名稱 -->
<bean id=
"methodCachePointCut"
class
=
"org.springframework.aop.support.RegexpMethodPointcutAdvisor"
>
<property name=
"advice"
>
<ref local=
"methodCacheInterceptor"
/>
</property>
<property name=
"patterns"
>
<list>
<value>.*find.*</value>
<value>.*get.*</value>
<value>.*list.*</value>
<value>.*List.*</value>
</list>
</property>
</bean>
<!-- 觸發更新緩存數據的方法-->
<bean id=
"methodCachePointCutAdvice"
class
=
"org.springframework.aop.support.RegexpMethodPointcutAdvisor"
>
<property name=
"advice"
>
<ref local=
"methodCacheAfterAdvice"
/>
</property>
<property name=
"patterns"
>
<list>
<value>.*create.*</value>
<value>.*update.*</value>
<value>.*delete.*</value>
<value>.*edit.*</value>
</list>
</property>
</bean>
</beans>
|
二、src目錄下增長ehcache.xml配置文件spring
<ehcache>
<defaultCache
maxElementsInMemory=
"1000"
eternal=
"false"
timeToIdleSeconds=
"120"
timeToLiveSeconds=
"120"
overflowToDisk=
"true"
/>
<cache name=
"DEFAULT_CACHE"
maxElementsInMemory=
"10000"
eternal=
"false"
timeToIdleSeconds=
"300000"
timeToLiveSeconds=
"600000"
overflowToDisk=
"true"
/>
</ehcache>
|
3、以上ehcahe的配置已基本完成,下一步是若是把這些配置在咱們Struts2+spring2.5+hibernate3項目上整合上去數據庫
其實只須要修改spring的配置文件便可apache
<
import
resource=
"classpath:cacheContext.xml"
/><br> <!-- 系統啓動表 -->
<bean id=
"systemsetupDao"
parent=
"hibernateTransactionProxy"
>
<property name=
"target"
>
<bean
class
=
"com.XX.rent.rentsysteup.dao.RentSyentemSetupDaoImp"
parent=
"genericHibernateDao"
>
<property name=
"hibernateTemplate"
>
<ref bean=
"hibernateTemplate"
/>
</property>
</bean>
</property>
</bean>
<bean id=
"systemsetupServiceTarget"
class
=
"com.XX.rent.rentsysteup.service.RentSyentemSetupServiceImpl"
>
<property name=
"syssetupdao"
>
<ref local=
"systemsetupDao"
/>
</property>
</bean>
<!-- 使用chcahe配置 -->
<bean id=
"systemsetupService"
class
=
"org.springframework.aop.framework.ProxyFactoryBean"
>
<property name=
"target"
>
<ref local=
"systemsetupServiceTarget"
/>
</property>
<property name=
"interceptorNames"
>
<list>
<value>methodCachePointCut</value>
<value>methodCachePointCutAdvice</value>
</list>
</property>
</bean>
|
完成試用,其餘的struts2,hibernate3的配置文件都不須要修改,所有由spring的AOP技術實現對攔截方法名的緩存處理緩存
原文出處:http://www.cnblogs.com/fangj/p/SSH2_ehcahe.html
app