精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-14
最后修改:2010-01-14
由于系统需求需要对各个接口进行key-value缓存(以参数为key,返回的对象为value),当然对于这种情况首先考虑到的是使用aop,前段时间看过aspectj的一些介绍,借此机会正好加以应用和体会一下,aspectj是AOP最早成熟的java实现,它稍微扩展了一下java语言,增加了一些keyword等,具体的aspectj的基本语法见[ur=http://today.java.net/pub/a/today/2003/12/26/ch3AspectJSyntaxBasics.html]这里[/url],进行缓存的框架使用较成熟的ehcache. <?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="/home/workspace/gzshine/trunk/ehcache"/> <cache name="DEFAULT_CACHE" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" /> </ehcache>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- ############## aspectj 4 ehcache ############# --> <aop:aspectj-autoproxy proxy-target-class="true"/> <bean id = "methodCacheAspectJ" class="com.***.shine.aspectj.MethodCacheAspectJ" > <property name="cache"> <ref local="methodCache" /> </property> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation"> <value>classpath:ehcache.xml</value> </property> </bean> <!-- 定义ehCache的工厂,并设置所使用的Cache name --> <bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <ref local="cacheManager" /> </property> <property name="cacheName"> <value>DEFAULT_CACHE</value> </property> </bean>
package com.***.shine.cache; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MethodCache { int second() default 0; }
package com.***.shine.aspectj; @Aspect public class MethodCacheAspectJ { Log logger = LogFactory.getLog(MethodCacheAspectJ.class); private Cache cache; /** * 设置缓存名 */ public void setCache(Cache cache) { this.cache = cache; } @Pointcut("@annotation(com.***.shine.cache.MethodCache)") public void methodCachePointcut(){ } @Around("methodCachePointcut()") public Object methodCacheHold(ProceedingJoinPoint joinPoint) throws Throwable{ String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Object result = null; String cacheKey = getCacheKey(targetName, methodName, arguments); Element element = cache.get(cacheKey); if (element == null) { try{ result = joinPoint.proceed(); }catch(Exception e){ logger.info(e); } if(result!=null){ try{ element = new Element(cacheKey, (Serializable) result); Class targetClass = Class.forName(targetName); Method[] method = targetClass.getMethods(); int second = 0; for(Method m:method){ if (m.getName().equals(methodName)) { Class[] tmpCs = m.getParameterTypes(); if(tmpCs.length==arguments.length){ MethodCache methodCache = m.getAnnotation(MethodCache.class); second = methodCache.second(); break; } } } if(second>0){ // annotation没有设second值则使用ehcache.xml中自定义值 element.setTimeToIdle(second); element.setTimeToLive(second); } cache.put(element); }catch(Exception e){ logger.info("!!!!!!!!!"+cacheKey+"!!!!!!!!!未能执行方法缓存"+e); } } } return element.getValue(); } 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++) { if (arguments[i] instanceof Date) { sb.append(".").append( DateUtil.datetoString((Date) arguments[i])); } else { sb.append(".").append(arguments[i]); } } } return sb.toString(); } }
@MethodCache(second=300) public List<Sort> getSort(int type,int parentid){ System.out.println("!!!!!!!!!!!!!没缓存到"); Row row = new Row(); row.put("type", type); row.put("parentid", parentid); return (List<Sort>)gz_Template.queryForList("sort.getSort", row); }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-11
sb.append(".").append(arguments[i]);
恐怕这一行代码还是会存在潜在问题。这要求参数对象实现自己的toString()方法。 |
|
返回顶楼 | |
发表时间:2010-07-29
这个是基于什么原理?
@Pointcut("@annotation(com.netease.shine.cache.MethodCache)") 对有应用com.netease.shine.cache.MethodCache进行注解的方法进行横切面拦截 |
|
返回顶楼 | |
浏览 3853 次