利用 Spring 跟 EHCache 做方法缓存处理〔转〕
利用 Spring 和 EHCache 做方法缓存处理〔转〕?利用 Spring 和 EHCache 做方法缓存处理〔转〕* WITHOUT WARRAN
利用 Spring 和 EHCache 做方法缓存处理〔转〕
?
利用 Spring 和 EHCache 做方法缓存处理〔转〕* WITHOUT WARRANTIES or CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.taha.interceptor;
import java.io.Serializable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
/**
* @author <a href="mailto:irbouh@gmail.com">Omar Irbouh</a>
* @since 2004.10.07
*/
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 void afterPropertiesSet() throws Exception {
????Assert.notNull(cache, "A cache is required. Use setCache(Cache) to provide one.");
??}
??/**
?? * 主方法
?? * 如果某方法可被缓存就缓存其结果
?? * 方法结果必须是可序列化的(serializable)
?? */
??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("looking for method result in cache");
????String cacheKey = getCacheKey(targetName, methodName, arguments);
????Element element = cache.get(cacheKey);
????if (element == null) {
??????//call target/sub-interceptor
??????logger.debug("calling intercepted method");
??????result = invocation.proceed();
??????//cache method result
??????logger.debug("caching 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();
??}
}
MethodCacheInterceptor 代码说明了:?
?????默认条件下,所有方法返回结果都被缓存了(methodNames 是 null)?
?????缓存区利用 IoC 形成?
?????cacheKey 的生成还包括方法参数的因素(译注:参数的改变会影响 cacheKey)?
使用 MethodCacheInterceptor?
下面摘录了怎样配置 MethodCacheInterceptor:
<bean id="methodCacheInterceptor" />
??</property>
</bean>
<bean id="methodCachePointCut" class="org.springframework.aop.framework.ProxyFactoryBean">
??<property name="target">
?? <bean class="org.taha.beans.MyBean"/>
??</property>
??<property name="interceptorNames">
????<list>
??????<value>methodCachePointCut</value>
????</list>
??</property>
</bean>