`

SpringAOP结合ehCache实现简单缓存实例

阅读更多
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简单缓存系统解决方案】中,我们将探讨如何利用Spring AOP(面向切面编程)和ehCache框架来构建一个高效、简单的缓存系统,以提升应用程序的性能。ehCache是一款流行的开源Java缓存库,它...

    spring3 hibernate4 ehcache实例

    本文将详细介绍如何在Spring3和Hibernate4环境下整合Ehcache,实现数据缓存功能,以提高应用性能。 1. **Spring3与Hibernate4整合** 在Spring3中配置Hibernate4,我们需要在配置文件中定义SessionFactory,并使用...

    aop例子aop例子

    本例子是一个关于如何在Spring框架中实现AOP的应用实例。 标题中的"aop例子aop例子"表明我们将探讨Spring AOP的实践应用。Spring是Java领域中最流行的框架之一,它提供了对AOP的强大支持,使得我们可以方便地创建和...

    ehcache的功能实现

    在本文中,我们将深入探讨Ehcache的功能实现以及如何与Spring框架进行集成,同时通过两个项目实例——`TestEhcacheSpring.zip`和`TestEhcache.zip`来具体说明。 ### Ehcache核心功能 1. **缓存管理**: Ehcache允许...

    maven+spring+ehcache

    总的来说,这个压缩包文件提供了一个基础的Java Web项目模板,展示了如何整合Maven、Spring、Spring MVC和Ehcache来实现一个具备缓存功能的Web应用。开发者可以通过学习和修改这个实例,加深对这些技术的理解并应用...

    spring mybatis ehcache

    在Spring中,Ehcache可以通过Spring Cache抽象进行配置和使用,使得缓存管理变得简单。 在这个"Struggle_ssm"项目中,我们可以预见到以下关键点: 1. **Spring配置**:项目会包含一个或多个XML配置文件,用于定义...

    EHCache 实例

    【EHCache实例详解】 EHCache是一款广泛使用的Java缓存库,尤其在Spring框架中作为缓存解决方案被广泛应用。...同时,结合Spring AOP和注解,我们可以轻松地在方法级别实现缓存控制,提升应用性能。

    EhCache缓存技术

    EhCache是一个强大的Java缓存框架,它被广泛用于提高应用程序的性能,通过存储经常访问的数据来减少数据库的负载。EhCache的核心特性包括...结合Spring的AOP功能,可以实现便捷的缓存管理,提升系统的响应速度和效率。

    SpringMVC+Mybatis+Spring+Shiro+ehcache整合配置文件

    Ehcache可以很好地与Spring集成,通过简单的配置即可实现缓存管理。 在整合这些技术时,首先需要在Spring的配置文件中定义bean,包括数据源、SqlSessionFactory(Mybatis的核心)、MapperScannerConfigurer(扫描...

    cglib-2.2.jar,ehcache-spring-annotations-1.1.2.jar

    `ehcache-spring-annotations-1.1.2.jar`则是Ehcache与Spring集成的特定版本,它允许开发者通过注解轻松地在Spring应用中启用和配置Ehcache缓存。 **Spring缓存抽象** 提供了一种统一的方式来管理和控制缓存,无论...

    AOP Cache源代码

    在IT行业中,Spring AOP(面向切面编程)和Ehcache是两个非常重要的概念,它们经常被结合在一起用于实现高效的应用程序缓存系统。在这个"AOP Cache源代码"项目中,我们可以看到如何利用这两者来提升应用性能。下面将...

    ehcache需要的jar包

    Ehcache是一个流行的Java缓存库,用于...通过将Ehcache与Spring AOP结合,开发者可以构建高性能的应用,利用缓存机制降低数据库压力,提高响应速度。在实际项目中,正确配置和使用Ehcache是优化应用性能的关键步骤。

    Spring基于注解的缓存配置--web应用实例

    在本实例中,我们将深入探讨如何在Spring框架中利用注解来实现缓存配置,特别是在Web应用程序中的实际应用。Spring Cache是一个强大的功能,它允许我们高效地管理应用程序中的数据,减少不必要的数据库查询,提高...

    Spring整合JBPM、日志、数据库、ehcache的配置文件

    在这个场景中,我们关注的是如何将Spring框架与JBPM(Business Process Management,业务流程管理)、日志记录、数据库以及ehcache缓存系统进行整合。这些组件在实际应用开发中扮演着至关重要的角色。下面将详细阐述...

    Ehcache例子

    在本文中,我们将深入探讨Ehcache的使用,以及它如何与Spring框架集成,以实现高效的数据缓存。 首先,Ehcache的核心组件`ehcache-core-2.6.0.jar`包含了所有必要的类和接口,使得我们可以在应用程序中配置和管理...

    spring的监听器和缓存.docx

    在Spring Boot中,我们可以利用Spring Cache抽象来实现缓存功能,支持多种缓存Provider,如 EhCache、Redis 或 Hazelcast。通过`@EnableCaching`在配置类上启用缓存,然后在方法上使用`@Cacheable`、`@CacheEvict`等...

    Spring整合Ecache

    本实例的环境 eclipse + maven + spring + ehcache + junit EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开 源Java分布式缓存。主要...

Global site tag (gtag.js) - Google Analytics