栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

@Retention自定义注解,切面缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

@Retention自定义注解,切面缓存

1.先创建一个自定义注解需要用到@Retention 注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodCache {


    
    int expireSeconds() default 60;

    
    String key() default "";

    
    boolean limitQuery() default true;

    
    String explain() default "";


}

上述注解定义好我们可以在方法上使用

@MethodCache(expireSeconds = 1200,key = "cacheKey",explain = "列表信息")

 2.定义切面进入的标准利用上述建的MethodCache注解

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.application.core.util.domain.Response;
import com.factory.annotation.MethodCache;
import com.factory.util.HashAlgorithms;
import com.factory.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.net.Httpcookie;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Aspect
@Order(value = 2)
@Component
public class MethodCacheAspect {

    @Resource
    private RedisUtil redisUtil;
    //定义MethodCacheKey唯一标识,方便对Key做统一的处理
    private final String METHOD_CACHE_KEY = "MethodCacheKey-";

    private static Logger log = LoggerFactory.getLogger(MethodCacheAspect.class);

    
    @Around("@annotation(methodCache)")
    public Object execute(ProceedingJoinPoint proceedingJoinPoint, MethodCache methodCache) throws Throwable {
            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = methodSignature.getMethod();

        if(StringUtils.isNotEmpty(methodCache.explain())){
            log.info("[MethodCache]加载方法{}",methodCache.explain());
        }else{
            log.info("[MethodCache]加载方法{}",method.getName());
        }
        // 解析请求参数
        List list = parseRequestParam(proceedingJoinPoint);
        // 根据方法获取相应的key
        String key = methodCache.key();
        if (StringUtils.isBlank(key)) {
            key = getSignature(method);
        }
        key =METHOD_CACHE_KEY + key + HashAlgorithms.mixHash(JSON.toJSonString(list));
        log.info("[MethodCacheKey]:{}",key);
        Object deserialize = tryGetFromCache(key);
        if (deserialize != null) {
            return deserialize;
        }
        Object proceed;
        if (methodCache.limitQuery()) {
            proceed = executeConcreteMethod(proceedingJoinPoint);
            redisUtil.set(key, JSON.toJSonString(proceed));
            redisUtil.expire(key, methodCache.expireSeconds(),TimeUnit.SECONDS);
        } else {
            // 允许查询
            proceed = executeConcreteMethod(proceedingJoinPoint);
        }
        return proceed;
    }

    
    private Object executeConcreteMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        return proceedingJoinPoint.proceed();
    }

    
    private Object tryGetFromCache(String key) {
        if(!redisUtil.hasKey(key)){
            return null;
        }
        String result = redisUtil.get(key);
//        log.info("[MethodCache]读取缓存中信息:{}",result);
        if(result != null){
            return JSONObject.parseObject(result,Response.class);
        }
        return null;
    }

    
    private List parseRequestParam(ProceedingJoinPoint proceedingJoinPoint) {
        // 方法参数解析
        int size = proceedingJoinPoint.getArgs().length;
        Object[] args = proceedingJoinPoint.getArgs();
        List argList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            if (args[i] instanceof HttpServletRequest) {
                HttpServletRequest request = (HttpServletRequest) args[i];
                argList.add(request.getParameterMap());
            } else if (args[i] instanceof HttpServletResponse || args[i] instanceof HttpSession
                    || args[i] instanceof Httpcookie) {
                continue;
            } else {
                argList.add(args[i]);
            }
        }
        return argList;
    }

    
    private String getSignature(Method method) {
        StringBuilder sb = new StringBuilder();
        String methodName = method.getName();
        if (StringUtils.isNotBlank(methodName)) {
            sb.append(method).append("#");
        }
        return sb.toString();
    }



}
 

3.现在就可以使用注解了切面缓存查询了

//缓存查询
@MethodCache(expireSeconds = 1200,key = "cacheKey",explain = "列表") 
@GetMapping(value = "findCacheKey")
    public Response findCacheKey(@RequestParam(required = true) String channelCode,@RequestParam(required = true)String comCode) {
        //上面用到@MethodCache注解 会先切面查询缓存 缓存没有查询到再进入此方法查询
    }
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号