luckystar +
send mail to luckystar sina weibo
关于订阅 luckystar's blog » Project »
分类:
标签:

结合Spring AOP和EHCache实现查找时将结果放入缓存,在更新或删除操作时清除缓存的功能。
项目结构如下: img 依赖的Jars如下: img

ehcache.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
  4. monitoring="autodetect">
  5. <!--
  6. <diskStore path="java.io.tmpdir" /> -->
  7. <diskStore path="d:/cachetmpdir"/>
  8. <defaultCache maxElementsInMemory="10000" eternal="false"
  9. timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
  10. maxElementsOnDisk="10000000" diskPersistent="false"
  11. diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
  12. <cache name="dbCache" maxElementsInMemory="10000"
  13. maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
  14. diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600"
  15. memoryStoreEvictionPolicy="LFU" />
  16. </ehcache>

applicationContext-cache.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ehcache="http://www.springframework.org/schema/cache"
  4. xmlns:cache="http://www.springframework.org/schema/task"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
  7. <bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  8. <property name="configLocation" value="ehcache.xml"></property>
  9. </bean>
  10. <bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  11. <property name="cacheManager" ref="defaultCacheManager"></property>
  12. <property name="cacheName" value="dbCache"></property>
  13. </bean>
  14. <!--find/create Cache拦截器-->
  15. <bean id="methodCacheInterceptor" class="com.hyxt.cache.ehcache.demo.MethodCacheInterceptor">
  16. <property name="cache" ref="ehCache"></property>
  17. </bean>
  18. <!--update/delete Cache拦截器-->
  19. <bean id="methodCacheAfterAdvice" class="com.hyxt.cache.ehcache.demo.MethodCacheAfterReturningAdvice">
  20. <property name="cache" ref="ehCache"></property>
  21. </bean>
  22. <bean id="methodCacheAfterReturningAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  23. <property name="advice" ref="methodCacheInterceptor"></property>
  24. <property name="patterns">
  25. <list>
  26. <value>.*find.*</value>
  27. <value>.*get.*</value>
  28. </list>
  29. </property>
  30. </bean>
  31. <bean id="methodCachePointcutAfterReturning" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  32. <property name="advice" ref="methodCacheAfterAdvice"></property>
  33. <property name="patterns">
  34. <list>
  35. <value>.*create.*</value>
  36. <value>.*update.*</value>
  37. <value>.*delete.*</value>
  38. </list>
  39. </property>
  40. </bean>
  41. </beans>

applicationContext.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context
  7. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  8. <import resource="applicationContext-cache.xml"></import>
  9. <context:component-scan base-package="com.hyxt"></context:component-scan>
  10. <bean id="testServiceTarget" class="com.hyxt.cache.ehcache.demo.TestService"></bean>
  11. <bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean">
  12. <property name="target" ref="testServiceTarget"></property>
  13. <property name="interceptorNames">
  14. <list>
  15. <value>methodCacheAfterReturningAdvice</value>
  16. <value>methodCachePointcutAfterReturning</value>
  17. </list>
  18. </property>
  19. </bean>
  20. </beans>

MethodCacheInterceptor.java:

  1. package com.hyxt.cache.ehcache.demo;
  2. import net.sf.ehcache.Cache;
  3. import net.sf.ehcache.Element;
  4. import org.aopalliance.intercept.MethodInterceptor;
  5. import org.aopalliance.intercept.MethodInvocation;
  6. import org.apache.commons.logging.Log;
  7. import org.apache.commons.logging.LogFactory;
  8. import org.springframework.beans.factory.InitializingBean;
  9. import org.springframework.util.Assert;
  10. /**
  11. * 该拦截器的作用是在执行方法时查询/新建Cache。
  12. * Created by qince on 2015/3/23.
  13. */
  14. public class MethodCacheInterceptor implements MethodInterceptor,InitializingBean {
  15. private final static Log log = LogFactory.getLog(MethodCacheInterceptor.class);
  16. private Cache cache;
  17. public Cache getCache() {
  18. return cache;
  19. }
  20. public void setCache(Cache cache) {
  21. this.cache = cache;
  22. }
  23. @Override
  24. public void afterPropertiesSet() throws Exception {
  25. Assert.notNull(cache,"Need a cache,please use setCache(Cache) to create it!");
  26. }
  27. @Override
  28. public Object invoke(MethodInvocation methodInvocation) throws Throwable {
  29. // 类名+方法名+方法参数作为Cache Key
  30. String className = methodInvocation.getThis().getClass().getName();
  31. String methodName = methodInvocation.getMethod().getName();
  32. Object[] arguments = methodInvocation.getArguments();
  33. String cacheKey = getCacheKey(className, methodName, arguments);
  34. log.debug("cacheKey:" + cacheKey);
  35. Element element = null;
  36. synchronized (this) {
  37. element = cache.get(cacheKey);
  38. if (null == element) {
  39. log.info("未从缓存查找到数据,从数据库查询。。");
  40. Object result = methodInvocation.proceed();
  41. element = new Element(cacheKey,result);
  42. cache.put(element);
  43. }
  44. else {
  45. log.info("从缓存中查找到数据 :" + cacheKey);
  46. }
  47. }
  48. return element.getValue();
  49. }
  50. public String getCacheKey(String className,String methodName,Object[] arguments) {
  51. StringBuffer stringBuffer = new StringBuffer();
  52. stringBuffer.append(className).append(".").append(methodName);
  53. if (null != arguments) {
  54. for (Object argument : arguments) {
  55. stringBuffer.append(".").append(argument);
  56. }
  57. }
  58. return stringBuffer.toString();
  59. }
  60. }

MethodCacheAfterReturningAdvice.java:

  1. package com.hyxt.cache.ehcache.demo;
  2. import net.sf.ehcache.Cache;
  3. import org.apache.commons.logging.Log;
  4. import org.apache.commons.logging.LogFactory;
  5. import org.springframework.aop.AfterReturningAdvice;
  6. import org.springframework.beans.factory.InitializingBean;
  7. import org.springframework.util.Assert;
  8. import java.lang.reflect.Method;
  9. import java.util.List;
  10. /**
  11. * 该类的作用是执行update/delete操作时,清除缓存
  12. * Created by qince on 2015/3/23.
  13. */
  14. public class MethodCacheAfterReturningAdvice implements AfterReturningAdvice,InitializingBean {
  15. private final static Log log = LogFactory.getLog(MethodCacheInterceptor.class);
  16. private Cache cache;
  17. public Cache getCache() {
  18. return cache;
  19. }
  20. public void setCache(Cache cache) {
  21. this.cache = cache;
  22. }
  23. @Override
  24. public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
  25. String className =o1.getClass().getName();
  26. System.out.println("className;" + className);
  27. // System.out.println("o:" + o.getClass().getName());
  28. System.out.println("method:" + method.getClass().getName());
  29. List cacheKeys =cache.getKeys();
  30. if (null != cacheKeys) {
  31. for (int i=0;i<cacheKeys.size();i++) {
  32. String cacheKey = cacheKeys.get(i).toString();
  33. if (cacheKey.startsWith(className)) {
  34. cache.remove(cacheKey);
  35. log.info("清除缓存 : " + cacheKey);
  36. }
  37. }
  38. }
  39. }
  40. @Override
  41. public void afterPropertiesSet() throws Exception {
  42. Assert.notNull(cache, "Need a cache,please use setCache(Cache) to create it!");
  43. }
  44. }

TestDao.java:

  1. package com.hyxt.cache.ehcache.demo;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. import org.springframework.stereotype.Repository;
  5. /**
  6. * Created by qince on 2015/3/23.
  7. */
  8. @Repository
  9. public class TestDao {
  10. Log log = LogFactory.getLog(TestDao.class);
  11. public Object getObject(String name) {
  12. log.info("从数据库查找,name=" + name);
  13. return "hello " + name;
  14. }
  15. public void updateObject(String name) {
  16. log.info("更新数据库");
  17. }
  18. }

TestService.java:

  1. package com.hyxt.cache.ehcache.demo;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.cache.annotation.CacheEvict;
  6. import org.springframework.cache.annotation.Cacheable;
  7. import org.springframework.stereotype.Service;
  8. /**
  9. * Created by qince on 2015/3/23.
  10. */
  11. public class TestService {
  12. private final static Log LOG = LogFactory.getLog(TestService.class);
  13. @Autowired
  14. private TestDao testDao;
  15. public Object getObject(String name) {
  16. return testDao.getObject(name);
  17. }
  18. public void updateObject(String name) {
  19. testDao.updateObject(name);
  20. }
  21. }

EHCacheTest.java:

  1. package com.hyxt.cache.ehcache.demo;
  2. import org.omg.CORBA.portable.ApplicationException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. /**
  6. * Created by qince on 2015/3/23.
  7. */
  8. public class EHCacheTest {
  9. public static void main(String[] args) {
  10. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  11. TestService testService = (TestService) applicationContext.getBean("testService");
  12. System.out.println("第一次查找并创建Cache。");
  13. testService.getObject("test");
  14. System.out.println("=============================");
  15. System.out.println("第二次从Cache中查找。");
  16. testService.getObject("test");
  17. System.out.println("=============================");
  18. System.out.println("第三次清除Cache。");
  19. testService.updateObject("test");
  20. System.out.println("=============================");
  21. System.out.println("第四次从数据库查找并放入Cache。");
  22. testService.getObject("test");
  23. }
  24. }

执行结果: img

作者:qincidong
出处:http://qincidong.github.io/blog/2015/03/24/spring-ehcache.html
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
分类: 标签:
友荐云推荐