AOP,当然需要拦截器,这里需要2个拦截器:
一个是方法执行前查找缓存的拦截器;(query方法执行前先查找是否有缓存,如果有,走缓存,如果没有,执行方法,并且把结果缓存)
另一个是方法执行后销毁缓存的拦截器;(update,insert,delete等方法执行后需要销毁缓存)
---------------------------------------------------------------------------------------------------------------------------------------
方法执行前的拦截器MethodCacheInterceptor.java:
package ehcache;
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;
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);
}else{
logger.debug("get result from cache");
}
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();
}
}
---------------------------------------------------------------------------------------------------------------------------------------
方法执行后的拦截器MethodCacheAfterAdvice.java:
package 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;
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.");
}
}
---------------------------------------------------------------------------------------------------------------------------------------
测试用的测试方法TestService.java:
package ehcache;
public class TestService{
public String testMethod(){
System.out.println("没走缓存,直接调用TestService.testMethod()");
return "1";
}
public void updateMethod(){
System.out.println("updateMethod");
}
public void insertMethod(){
System.out.println("insertMethod");
}
public void deleteMethod(){
System.out.println("deleteMethod");
}
}
---------------------------------------------------------------------------------------------------------------------------------------
缓存配置文件ehcache.xml:
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="testCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="150"
timeToLiveSeconds="150"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
缓存配置文件ehcache-config.xml
<beans>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>src/ehcache/ehcache.xml</value>
</property>
</bean>
<bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref local="cacheManager"/>
</property>
<property name="cacheName">
<value>testCache</value>
</property>
</bean>
<!-- 创建cache拦截器 -->
<bean id="methodCacheInterceptor" class="ehcache.MethodCacheInterceptor">
<property name="cache">
<ref local="methodCache" />
</property>
</bean>
<!-- 销毁cache拦截器 -->
<bean id="methodCacheAfterAdvice" class="ehcache.MethodCacheAfterAdvice">
<property name="cache">
<ref local="methodCache" />
</property>
</bean>
<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheInterceptor"/>
</property>
<property name="patterns">
<list>
<value>.*TestService.testMethod</value>
</list>
</property>
</bean>
<bean id="methodCacheDestory" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheAfterAdvice"/>
</property>
<property name="patterns">
<list>
<value>.*TestService.update*</value>
<value>.*TestService.insert*</value>
<value>.*TestService.delete*</value>
</list>
</property>
</bean>
</beans>
---------------------------------------------------------------------------------------------------------------------------------------
Spring配置文件applicationContext.xml
<beans default-autowire="byName">
<import resource="ehcache-config.xml"/>
<bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean" >
<property name="target">
<bean class="ehcache.TestService"/>
</property>
<property name="interceptorNames">
<list>
<value>methodCachePointCut</value>
<value>methodCacheDestory</value>
</list>
</property>
</bean>
</beans>
---------------------------------------------------------------------------------------------------------------------------------------
测试用Main方法:
package ehcache;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class TestMain {
public static void main(String args[]) throws Exception{
ApplicationContext ctx = new FileSystemXmlApplicationContext("src/ehcache/applicationContext.xml");
TestService t = (TestService)ctx.getBean("testService");
System.out.println("第一次调用:" + t.testMethod());
System.out.println("第二次调用:" + t.testMethod());
System.out.print("更新操作:");
t.updateMethod();
System.out.println("第三次调用:" + t.testMethod());
}
}
---------------------------------------------------------------------------------------------------------------------------------------
运行结果:
没走缓存,直接调用TestService.testMethod()
第一次调用:1
第二次调用:1
更新操作:updateMethod
没走缓存,直接调用TestService.testMethod()
第三次调用:1
可以看到,第一次调用时没走缓存,第二次就走缓存
然后执行update操作,执行完后销毁缓存
第三次调用,又没走缓存。
分享到:
相关推荐
在本篇【Spring AOP+ehCache简单缓存系统解决方案】中,我们将探讨如何利用Spring AOP(面向切面编程)和ehCache框架来构建一个高效、简单的缓存系统,以提升应用程序的性能。ehCache是一款流行的开源Java缓存库,它...
本文将详细介绍如何在Spring3和Hibernate4环境下整合Ehcache,实现数据缓存功能,以提高应用性能。 1. **Spring3与Hibernate4整合** 在Spring3中配置Hibernate4,我们需要在配置文件中定义SessionFactory,并使用...
本例子是一个关于如何在Spring框架中实现AOP的应用实例。 标题中的"aop例子aop例子"表明我们将探讨Spring AOP的实践应用。Spring是Java领域中最流行的框架之一,它提供了对AOP的强大支持,使得我们可以方便地创建和...
在本文中,我们将深入探讨Ehcache的功能实现以及如何与Spring框架进行集成,同时通过两个项目实例——`TestEhcacheSpring.zip`和`TestEhcache.zip`来具体说明。 ### Ehcache核心功能 1. **缓存管理**: Ehcache允许...
总的来说,这个压缩包文件提供了一个基础的Java Web项目模板,展示了如何整合Maven、Spring、Spring MVC和Ehcache来实现一个具备缓存功能的Web应用。开发者可以通过学习和修改这个实例,加深对这些技术的理解并应用...
在Spring中,Ehcache可以通过Spring Cache抽象进行配置和使用,使得缓存管理变得简单。 在这个"Struggle_ssm"项目中,我们可以预见到以下关键点: 1. **Spring配置**:项目会包含一个或多个XML配置文件,用于定义...
【EHCache实例详解】 EHCache是一款广泛使用的Java缓存库,尤其在Spring框架中作为缓存解决方案被广泛应用。...同时,结合Spring AOP和注解,我们可以轻松地在方法级别实现缓存控制,提升应用性能。
EhCache是一个强大的Java缓存框架,它被广泛用于提高应用程序的性能,通过存储经常访问的数据来减少数据库的负载。EhCache的核心特性包括...结合Spring的AOP功能,可以实现便捷的缓存管理,提升系统的响应速度和效率。
Ehcache可以很好地与Spring集成,通过简单的配置即可实现缓存管理。 在整合这些技术时,首先需要在Spring的配置文件中定义bean,包括数据源、SqlSessionFactory(Mybatis的核心)、MapperScannerConfigurer(扫描...
`ehcache-spring-annotations-1.1.2.jar`则是Ehcache与Spring集成的特定版本,它允许开发者通过注解轻松地在Spring应用中启用和配置Ehcache缓存。 **Spring缓存抽象** 提供了一种统一的方式来管理和控制缓存,无论...
在IT行业中,Spring AOP(面向切面编程)和Ehcache是两个非常重要的概念,它们经常被结合在一起用于实现高效的应用程序缓存系统。在这个"AOP Cache源代码"项目中,我们可以看到如何利用这两者来提升应用性能。下面将...
Ehcache是一个流行的Java缓存库,用于...通过将Ehcache与Spring AOP结合,开发者可以构建高性能的应用,利用缓存机制降低数据库压力,提高响应速度。在实际项目中,正确配置和使用Ehcache是优化应用性能的关键步骤。
在本实例中,我们将深入探讨如何在Spring框架中利用注解来实现缓存配置,特别是在Web应用程序中的实际应用。Spring Cache是一个强大的功能,它允许我们高效地管理应用程序中的数据,减少不必要的数据库查询,提高...
在这个场景中,我们关注的是如何将Spring框架与JBPM(Business Process Management,业务流程管理)、日志记录、数据库以及ehcache缓存系统进行整合。这些组件在实际应用开发中扮演着至关重要的角色。下面将详细阐述...
在本文中,我们将深入探讨Ehcache的使用,以及它如何与Spring框架集成,以实现高效的数据缓存。 首先,Ehcache的核心组件`ehcache-core-2.6.0.jar`包含了所有必要的类和接口,使得我们可以在应用程序中配置和管理...
在Spring Boot中,我们可以利用Spring Cache抽象来实现缓存功能,支持多种缓存Provider,如 EhCache、Redis 或 Hazelcast。通过`@EnableCaching`在配置类上启用缓存,然后在方法上使用`@Cacheable`、`@CacheEvict`等...
本实例的环境 eclipse + maven + spring + ehcache + junit EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开 源Java分布式缓存。主要...