美文网首页
使用 AOP 和注解实现方法缓存(上)

使用 AOP 和注解实现方法缓存(上)

作者: ByteBlade | 来源:发表于2016-09-25 18:25 被阅读474次

    前言

    做web开发中,提高系统效率,经常用到缓存操作。但是代码中到处都是Cache的操作,为了提高代码的质量,在大神的指导下使用面向切面编程,提供一个基于Method的统一的Cache切入功能。

    启用@AspectJ支持

    通过在你的Spring的配置中引入下列元素来启用Spring对@AspectJ的支持:

    <aop:aspectj-autoproxy/>
    

    自定义一个Cache注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    public @interface Cache {
        /**     * 缓存过期时间,单位是秒     */    
        int expire() default 10;
    }
    
    

    完成切面

    使用注解来创建切面,around方法获取缓存值,如果没有命中到缓存值。应该调用目标函数,通过目标函数计算实际值。

    @Aspect
    @Component
    public class CacheIntercepter{
        @Around("@annotation(com.spring.aop.annoation.Cache)")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            if (joinPoint == null) {
                return  null;
            }
            String key = getKey(joinPoint);
            CacheClient client = new CacheClient();
            String clientValue = client.getValue(key);
            if (clientValue != null) {
                return clientValue;
            }
            //如果没有命中到缓存值。应该调用目标函数,通过目标函数计算实际值。
            return joinPoint.proceed();
        }
    
        /**
         * 根据参数生成cachekey
         * @param joinPoint
         * @return
         */
        private String getKey(ProceedingJoinPoint joinPoint) {
            String result = "";
            if (joinPoint.getArgs() == null) {
                return result;
            }
            for (Object key : joinPoint.getArgs()) {
                if (key != null) {
                    result += "_" + key.toString();
                }
            }
            return result;
        }
    }
    

    缓存客户端的实现

    为简化起见,假设key为空值的时候,缓存值为null;

    public class CacheClient {
        public String getValue(String key){
            if (key == null || "".equals(key)) {
                System.out.println("未命中cache");
            } else {
                System.out.println("命中cache");
                return "success";
            }
            return  null;
        }
    }
    

    测试用咧

    
    public class CacheTest extends AbstractTest{
    
        @Autowired
        private UserService userService;
    
        @Test
        public void test(){
            {
                String cache_result = userService.getId("12");
                System.out.println("命中cache的结果:"+cache_result);
            }
    
            {
                String uncache_result = userService.getId(null);
                System.out.println("未命中cache的结果:"+uncache_result);
            }
        }
    }
    

    运行结果

    命中cache
    命中cache的结果:success
    未命中cache
    未命中cache的结果:我的计算值
    

    第一版的代码请移步github,注意是feature-aspectj-aop分支。

    相关文章

      网友评论

          本文标题:使用 AOP 和注解实现方法缓存(上)

          本文链接:https://www.haomeiwen.com/subject/lmpfyttx.html