import java.lang.annotation.*;

/**
 * 元注解 用来标识查询数据库的方法
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseMemCache {

    /**
     * 缓存超时时间控制,> 0 则做超时控制
     * @return
     */
    int expireSeconds() default 30;
}

=================================================







/**
 * AOP实现cache缓存处理(缓存到静态对象)
 *
 * @decr
 * @author jlchent
 * @date 2018年11月03日
 *
 */
@Component
@Aspect
public class MemCacheAspect {

    private static final Logger logger = LoggerFactory.getLogger(MemCacheAspect.class);

    /**
     * 数据缓存
     */
    private  static Hashtable<String, Object> dataTable = new Hashtable<>();
    
    /**
     * 超时控制
     */
    private  static Hashtable<String, Long> timeoutTable = new Hashtable<>();

    

    /**
     * 拦截所有元注解cacheCache注解的方法
     */
    @Pointcut("@annotation(cn.com.framework.annotation.UseMemCache)")
    public void pointcutMethod() {
    }

    
    private String saveObjToMem(String cacheKey, Object obj, int expireSeconds){
        dataTable.put(cacheKey, obj);

        Long expireTime = System.currentTimeMillis() + expireSeconds*1000;
        timeoutTable.put(cacheKey, expireTime);
        
        return "OK";
    }
    
    private String saveObjToMem(String cacheKey, Object obj){
        dataTable.put(cacheKey, obj);
        return "OK";
    }
    
    private Object getObjFromMem(String cacheKey) {
        Long expireTime = timeoutTable.get(cacheKey);
        Long currentTime = System.currentTimeMillis();
        if (null != expireTime && currentTime > expireTime) {
            //过期清空
            dataTable.remove(cacheKey);
            timeoutTable.remove(cacheKey);
            return null;
        }else
        return dataTable.get(cacheKey);
    }
    
    
    /**
     * 环绕处理,先从cache里获取缓存,查询不到,就通过method查询, 然后再保存到cache缓存里
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("pointcutMethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 前置:从cache里获取缓存
        // 先获取目标方法参数
        long startTime = System.currentTimeMillis();
        Object[] args = joinPoint.getArgs();
        String pragrm = "";
        if (args != null && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                pragrm = "_"+pragrm + String.valueOf(args[i]) ;
            }
        }
        // 获取目标方法所在类
        String target = joinPoint.getTarget().toString();
        String className = target.split("@")[0];
        // 获取目标方法的方法名称
        String methodName = joinPoint.getSignature().getName();
        int expireSeconds = 0;
            
        
        try {
            Class<?> clz = Class.forName(className);
            Class<?>[] classes = null;
            if (args != null && args.length > 0) {
                classes = new Class[args.length];
                for (int i = 0; i < classes.length; i++) {
                    classes[i] = args[i].getClass();
                }
            }

            Method method = clz.getMethod(methodName, classes);
            
            
            UseMemCache useMemCache = method.getAnnotation(UseMemCache.class);

            if (useMemCache != null && useMemCache.expireSeconds() > 0) {
                expireSeconds = useMemCache.expireSeconds();
            }

        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
            logger.warn("类包"+className+"不存在", e1);
            throw e1;
        }

        // cache中key格式: applId:方法名称
        String cacheKey =  className + "." + methodName + pragrm;

        Object obj =  getObjFromMem(cacheKey);
        
        
        if (obj != null) {
        
            logger.debug("cache的VALUE值类型:" + obj.getClass().getName());
            return obj;
        }
        long endTime = System.currentTimeMillis();
        logger.debug("cache缓存AOP处理所用时间(毫秒):" + (endTime - startTime));
        logger.info("**********没有从cache查到数据**********");

        logger.info("**********开始通过Method查询数据**********");
        obj = joinPoint.proceed();
        
        if (obj == null) {
            logger.info("**********获取到null数据**********");
            return null;
        }
        
        // 后置:将数据库查到的数据保存到cache
        String code = "";
        if (expireSeconds > 0) {
            code = saveObjToMem(cacheKey, obj, expireSeconds);
        } else {
            code = saveObjToMem(cacheKey, obj);
        }
        if (("OK").equals(code)) {
            logger.info("**********数据成功保存到cache缓存!!!**********");
            logger.info("MeM的KEY值:" + cacheKey);
            logger.info("cache的VALUE值类型:" + obj.getClass().getName());
        }
        return obj;
    }

}