我们都知道
Hibernate可以用ehcache来作为Second Level Cache.主要是针对POJO的缓存,而且缓存的读取
在
Hibernate中是写死.实际运用中感觉很不灵活.今天看到一篇介绍利用
Spring Interceptor 来缓存指定
方法结果的例子
,感觉很不错,充分体会到AOP的强大力量 :)
首先配置
ehcache.xml
字串3
maxElementsInMemory=
"300"
eternal=
"false"
timeToIdleSeconds=
"500"
timeToLiveSeconds=
"500"
overflowToDisk=
"true"
/>
|
接下在Spring配置文件中定义Ehcache组件
>
|
建立我们自己的方法拦截器
MethodCacheInterceptor
.
MethodCacheInterceptor
实现了
org.aopalliance.intercept.MethodInterceptor
接口
.
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.springframework.beans.factory.InitializingBean;
/**
*
拦截器
,
用于缓存方法返回结果
.
*
*
@version
$Id:
MethodCacheInterceptor.java
v
1.0
2004
-
11
-
28
14:57:00
Znjq
Exp
$
*/
public
class
MethodCacheInterceptor
implements
MethodInterceptor,
InitializingBean {
private
Cache cache;
/**
*
sets
cache
name
to
be
used
*/
public
void
setCache(Cache cache) {
this
.cache = cache;
}
/*
* (non-Javadoc)
*
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
public
Object invoke(MethodInvocation invocation)
throws
Throwable {
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
Object result;
String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = cache.get(cacheKey);
if
(element ==
null
) {
//call target/sub-interceptor
result = invocation.proceed();
//cache method result
element =
new
Element(cacheKey, (Serializable) result);
cache.put(element);
}
return
element.getValue();
}
/**
*
creates
cache
key:
targetName.methodName.argument0.argument1...
*/
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();
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public
void
afterPropertiesSet()
throws
Exception {
//
TODO
Auto-generated method stub
}
}
|
invoke
方法中
,
首先根据
key
查询缓存
(key=className + methodName + arguments)
,
缓存中存在则返回
,
否之调用
invocation.proceed()
返回结果
.
在
Spring
配置文件中定义拦截器
|
这里org.springframework.aop.support.RegexpMethodPointcutAdvisor是一个正规表达式切入点,
使用Perl 5的正规表达式的语法, 基Jakarta ORO。(有空写个文档,自己研究一下).
|
org.taha.beans.MyBean是我们需要做缓存处理的类.
methodCachePointCut中
|
则是指定的模式匹配方法
,
对应于org.taha.beans.MyBean中的方法. 这里指定了2个方法需要做缓存处理.
呵呵,就是这么简单.这样每次对org.taha.beans.MyBean的
methodOne
方法进行调用
,
都会首先从缓存查找
,
其次才会查询数据库
.
这样我就不需要在
xx.hbm.xml
来指定讨厌的
cache
了
.
也不需要在开发阶段来关心缓存
.
一切
AOP
搞定
.. ^_^