使用java注解+切面实现redis缓存注入

公司有一个项目,使用dubbo提供服务,接口大部分是查询数据接口,数据需要redis缓存以减少服务器压力,如果每个接口都手动写代码实现redis缓存的话,工作量很大,因此思考只用一套代码实现redis功能注入,无需修改业务代码。

先定义一个注解:

@Target(METHOD)
@Retention(RUNTIME)
public @interface RedisCache {

    long time() default 1;

    TimeUnit timeunit() default TimeUnit.DAYS;

}

需要用到切面,在pom中加入:

        
            org.aspectj
            aspectjrt
            1.8.10
        
        
            org.aspectj
            aspectjweaver
            1.8.10
        

定义切面类RedisCacheAspect,并在spring配置文件中注入:

    @Around(value="@annotation(com.mycache.RedisCache)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //System.out.println("环绕通知前....");
        Class clazz = joinPoint.getTarget().getClass();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

        StringBuilder keyB = new StringBuilder();
        keyB.append(clazz.getSimpleName()).append("_").append(method.getName());

        String[] argNames = null;
        Object[] argValues = null;
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        argNames = u.getParameterNames(method);
        argValues = joinPoint.getArgs();

        if(argNames.length==argValues.length){
            for (int i = 0; i < argNames.length; i++) {
                   keyB.append("_").append(argValues[i]);
            }
        }
        String key = keyB.toString();
        Object obj = redissonClient.getBucket(key).get();
        if(obj!=null){
                return obj;
        }
        else{
            obj = joinPoint.proceed();
        }

        if(obj!=null){
                if(method.isAnnotationPresent(RedisCache.class)){
                    RedisCache redisCache = method.getAnnotation(RedisCache.class);
                    redissonClient.getBucket(key).set(obj, redisCache.time(), redisCache.timeunit());
                }
        }

        //System.out.println("环绕通知后....");
        return obj;
    }

最后在业务方法上加入注解:

    @Override
    @RedisCache(time = 10,timeunit = TimeUnit.DAYS)
    public PageInfo getRadioCategories(Integer offset, Integer limit) throws BaseDubboException, BaseDubboServerException {
        JSONObject params = new JSONObject();
        params.put("offset", RadioV2CheckUtil.checkOffset(offset));
        params.put("limit", RadioV2CheckUtil.checkLimit(limit));

        String result = spService.call(BIFROST_SP_URL.RADIO_CATEGORIES, params);
        return RadioUtil.getJsonObjectPageInfo(result,Category.class);
    }

注解参数中可以根据不同接口的需求配置不同的redis超时时间。如果将来业务有变化,不需要缓存了,去掉注解就可,非常方便。

转载于:https://my.oschina.net/u/4006066/blog/2252370

你可能感兴趣的:(数据库,java,runtime)