Memcache+Spring AOP
来源:互联网 发布:sqlserver去重复查询 编辑:程序博客网 时间:2024/06/10 15:53
<aop:aspectj-autoproxy proxy-target-class='false'/>
proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。
如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。
如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。
package org.digdata.swustoj.aop.cache;import java.lang.reflect.Method;import java.util.List;import java.util.Map;import org.apache.log4j.Logger;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.digdata.swustoj.base.IMemCacheTemplate;import org.digdata.swustoj.model.CacheAccess;import org.digdata.swustoj.model.CacheFlush;import org.digdata.swustoj.util.ClassUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * * @author wwhhf * @since 2016年6月1日 * @comment 缓存切面管理 order值越小,顺序越高 cacheKey->className.methodName(args).version * cacheValue->data versionKey->className.version cacheValue->Integer */@Order(2)@Aspect@Componentpublic class MemCacheAspect { private static Logger logger = Logger.getLogger(MemCacheAspect.class); private static final Class VERSION_KEY_TYPE = Long.class; private static final String VERSION_SUFFIX = "version"; @Autowired private IMemCacheTemplate iMemCacheTemplate = null; /** * * @author wwhhf * @since 2016年6月2日 * @comment 修改方法 */ @Pointcut("execution(* org.digdata.swustoj.mybatis.dao.impl.*.*(..)) " + "|| execution(* org.digdata.swustoj.service.impl.*.*(..)) ") public void methods() { } /** * * @author wwhhf * @since 2016年6月1日 * @comment 先进行访问缓存,若命中则直接返回,否则继续执行方法 * @param joinpoint * @throws Throwable */ @Around("methods()") public Object cacheAccess(ProceedingJoinPoint joinpoint) throws Throwable { String clazzName = joinpoint.getTarget().getClass().getName(); String methodName = joinpoint.getSignature().getName(); Object[] args = joinpoint.getArgs(); Method method = ((MethodSignature) joinpoint.getSignature()) .getMethod(); boolean hasAnnotation = method.isAnnotationPresent(CacheAccess.class); if (hasAnnotation) {// 存在需要缓存数据的注解 String version_key = getVersionKey(clazzName);// 获取缓存版本号的key Long version_value = (Long) this.iMemCacheTemplate.getObject( version_key, VERSION_KEY_TYPE); // 获取缓存版本号 if (version_value == null) { // 版本号过期了,重新建立缓存版本号,该类以前的缓存全部过期 this.iMemCacheTemplate.set(version_key, version_value = getNextVersionValue());// 重新设置缓存版本号 System.out.println("缓存初始化: " + version_key + " -> " + version_value); String cache_key = ClassUtil.getMethodInfo(clazzName, methodName, args, version_value);// 获得缓存的key // ============================================ Object cache_value = joinpoint.proceed(args);// 缓存未命中 // ============================================ System.out.println("缓存未命中: " + cache_key); this.iMemCacheTemplate.set(cache_key, cache_value);// 缓存数据 return cache_value; } else {// 版本号未过期,查询该类此版本的缓存 CacheAccess annotation = method .getAnnotation(CacheAccess.class);// 获得注解 Class clazz = annotation.type(); // 获得json的class String cache_key = ClassUtil.getMethodInfo(clazzName, methodName, args, version_value);// 获得cache_key Object cache_value = null; if (clazz == String.class) { // String cache_value = this.iMemCacheTemplate.getString(cache_key); } else if (clazz == List.class) { // List Class subClazz = annotation.subType(); cache_value = this.iMemCacheTemplate.getList(cache_key, subClazz); } else if (clazz == Map.class) { // Map cache_value = this.iMemCacheTemplate.getMap(cache_key); } else { // Object cache_value = this.iMemCacheTemplate.getObject(cache_key, clazz); } if (cache_value == null) { // 缓存未命中,需要缓存数据 System.out.println("缓存未命中: " + cache_key); // ==================================== cache_value = joinpoint.proceed(args); // ==================================== this.iMemCacheTemplate.set(cache_key, cache_value); } else { // 缓存命中 System.out.println("缓存命中: " + cache_key); } return cache_value; } } else {// 不存在注解 return joinpoint.proceed(args); } } /** * * @author wwhhf * @since 2016年6月1日 * @comment 先进行缓存清除,再执行方法 * @param joinpoint * @throws Throwable */ @Around("methods()") public Object cacheFlush(ProceedingJoinPoint joinpoint) throws Throwable { String clazzName = joinpoint.getTarget().getClass().getName(); Object[] args = joinpoint.getArgs(); Method method = ((MethodSignature) joinpoint.getSignature()) .getMethod(); boolean hasAnnotation = method.isAnnotationPresent(CacheFlush.class); if (hasAnnotation) {// 存在清除缓存的注解 improveVersion(clazzName);// 提高缓存的版本号 } return joinpoint.proceed(args); } /** * @author wwhhf * @since 2016年6月5日 * @comment 提高相应类的版本 * @param clazzName */ private void improveVersion(String clazzName) { // 获取缓存版本号的key String version_key = getVersionKey(clazzName); // 获取缓存版本号 Long version = (Long) this.iMemCacheTemplate.getObject(version_key, VERSION_KEY_TYPE); if (version != null) { // 版本号过期则不管,让查询统一处理 // 版本号未过期,提高版本号 this.iMemCacheTemplate.set(version_key, version = getNextVersionValue()); System.out.println("缓存版本提高: " + version_key + " -> " + version); } } /** * * @author wwhhf * @since 2016年6月2日 * @comment 获取类名对应的缓存版本号 * @param className * @return */ private String getVersionKey(String className) { StringBuffer sb = new StringBuffer(className).append(".").append( VERSION_SUFFIX); return sb.toString(); } /** * * @author wwhhf * @since 2016年6月2日 * @comment 获取类名对应的下一次的缓存版本号(时间戳) * @param className * @return */ private Long getNextVersionValue() { return System.currentTimeMillis(); }}
package org.digdata.swustoj.model;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;/** * * @author wwhhf * @since 2016年6月1日 * @comment 表示该方法需要先进行缓存清除,再执行该方法 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic @interface CacheFlush {}
/** * * @author wwhhf * @since 2016年5月26日 * @comment 条件查询标签 * @param search_ids * @param search_name * @param condition * @param page * @param rows * @return */ @CacheAccess(type = List.class, subType = Tags.class) public List<Tags> selectTags(List<Integer> search_ids, String search_name, String condition, Integer page, Integer rows); /** * * @author wwhhf * @since 2016年5月26日 * @comment 条件查询标签的数量 * @param search_ids * @param search_name * @param condition * @param page * @param rows * @return */ @CacheAccess(type = Integer.class) public Integer selectTagsNum(List<Integer> search_ids, String search_name, String condition); /** * * @author wwhhf * @since 2016年5月26日 * @comment 批量删除标签 * @param tids * @return */ @CacheFlush public Boolean deleteTags(List<Integer> tids); /** * * @author wwhhf * @since 2016年5月26日 * @comment 添加标签 * @param record * @return */ @CacheFlush public Boolean insertTags(Tags record); /** * * @author wwhhf * @since 2016年5月26日 * @comment 更新标签 * @param record * @return */ @CacheFlush public Boolean updateTags(Tags record);
原先版本的缓存策略:Mybatis一级缓存+mysql自身缓存
现版本缓存策略:memcache+原版本
时间对比:
原:400多ms
现:160左右ms
不足
service层缓存建议不使用:service调用别的dao层的修改方法,一定要通过service层调用,否则会出现缓存同步问题。
0 0
- Memcache+Spring AOP
- spring 3.1.0.M 注解MVC + filter + AOP + memcache + C3P0
- spring 3.1.0.M 注解MVC + filter + AOP + memcache + C3P0
- AOP、Spring的AOP
- AOP--Spring AOP
- Spring AOP 嵌套AOP
- spring AOP
- Spring AOP
- Spring AOP
- spring aop
- Spring AOP
- spring AOP
- spring aop
- Spring aop
- Spring-AOP
- Spring AOP
- spring aop
- spring aop
- su: 无法设置用户ID: 资源暂时不可用
- HashSet和HashMap比较
- http接口调用
- IOS更改UITabBarItem的图片及字体颜色
- 关于Android的style和theme
- Memcache+Spring AOP
- C++中auto型的详细解释
- FZU 2236 第十四个目标(严格上升子序列个数 离散化 + 树状数组)
- Linux下查看文件和文件夹大小
- lua select(a,b)函数
- 反射访问方法
- _cdel和thiscall调用约定
- UISearchController IOS8之后推荐使用的搜索控件
- js实现购物车