分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

使用自定义annotation接口进行aspectj动态缓存

发布时间:2023-09-06 01:10责任编辑:傅花花关键词:缓存

由于系统需求需 要对各个接口进行key-value缓存(以参数为key,返回的对象为value),

当然对于这种情况首先考虑到的是使用aop,前段时间看过 aspectj的一些介绍,

借此机会正好加以应用和体会一下,aspectj是AOP最早成熟的java实现,

它稍微扩展了一下java语言,增加了一些 keyword等,具体的aspectj的基本语法见这里,进行缓存的框架使用较成熟的ehcache.
下面开始进行配置
首先是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> ?

这个的DEFAULT_CACHE是默认配置,最大的缓存数为10000,时间为一个小时

接下来的是spring下的配置

<!-- ############## ?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> ?

<aop:aspectj-autoproxy proxy-target-class="true"/>

是为aspectj在所有class下开启自动动态代理

<bean id="cacheManager">指定刚刚的ehcache配置文件

接下来编写一个自定义的annotation

@Target({ElementType.METHOD,ElementType.TYPE}) ??@Retention(RetentionPolicy.RUNTIME) ??@Documented ??public @interface MethodCache { ??????int second() default 0; ???} ?

<bean id = "methodCacheAspectJ">是一个aspectj进行Pointcuts和Advice的类需注入methodCache

@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(); ??????} ??} ?

@Pointcut("@annotation(com.netease.shine.cache.MethodCache)")

对有应用com.netease.shine.cache.MethodCache进行注解的方法进行横切面拦截

@Around("methodCachePointcut()")

并在Advice中处理这个Pointcut,这里的的Advice使用的是Around(环绕通知)

String cacheKey = getCacheKey(targetName, methodName, arguments);

接下来使用类型,方法名,参数为key进入缓存处理

Element element = cache.get(cacheKey);

当然如果在cache队列中取得非null对象则直接返回该对象

MethodCache methodCache = m.getAnnotation(MethodCache.class);

second = methodCache.second();

取得second的值(缓存的时间,如在@annotation中无重写只为int second() default 0)

element.setTimeToIdle(second);

element.setTimeToLive(second);

如果非零则重新设置缓存时间

@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); ??} ?

使用自定义annotation接口进行aspectj动态缓存

原文地址:http://www.cnblogs.com/anstoner/p/7514086.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved