使用自定义注解和Spring AOP实现缓存

1、注解类

package com.dh1027.login.annotation;

import java.lang.annotation.*;

/**
 * 缓存注解
 * Created by heyj2 on 2018/7/24.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cached {
    String cacheDescription();
}

2、切面类

package com.dh1027.login.annotation;

import com.dh1027.login.cache.CachedDataMapZ;
import com.dh1027.login.controller.LoginController;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 缓存切面
 * Created by heyj2 on 2018/7/12.
 */
@Aspect
@Component
public class CachedAdvice {
    private Logger logger = LoggerFactory.getLogger(LoginController.class);
    protected static char chr = '_';
    private CachedDataMapZ<Object> cachedDataMapZ = new CachedDataMapZ<>();

    @Pointcut("execution(public * *..*(..))")
    public void cache() {
    }

    /**
     *  环绕通知
     * @param joinPoint ProceedingJoinPoint
     * @param cachedAnnotation 缓存描述
     * @return
     * @throws Throwable
     */
    @Around("cache() && @annotation(cachedAnnotation)")
    public Object addAroundCache(ProceedingJoinPoint joinPoint, Cached cachedAnnotation) throws Throwable {
        String[] key = genKey(joinPoint.getArgs(), cachedAnnotation.cacheDescription(),joinPoint.getSignature());
        Object o = cachedDataMapZ.get(key);
       if(o != null){
           return o;
       }else {
           Object o1 = joinPoint.proceed();
           cachedDataMapZ.setMyData(o1,key);
           return o1;
       }

    }

    /**
     * 生成缓存key
     * @param parames 方法的参数
     * @param cacheDescription 缓存描述
     * @param signature 方法签名
     * @return
     */
    private String[] genKey(Object[] parames, String cacheDescription, Signature signature) {
        if (null == cacheDescription  || signature == null) {
            return new String[]{};
        }
        StringBuilder param = new StringBuilder().append(cacheDescription).append(chr).append(signature.toString()).append(chr);
        for (Object obj : parames) {
            param.append(obj.toString()).append(chr);
        }
        param.deleteCharAt(param.length()-1);
        return param.toString().split(String.valueOf(chr));
    }

}

3、缓存类

package com.dh1027.login.cache;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public  class CachedDataMapZ<T> {
    private static Log log = LogFactory.getLog(CachedDataMapZ.class);
    protected Map<String, T> mapdata = new HashMap();
    protected char chr = '_';
    protected int sizelimit = 100;
    protected long deltatime = 86400000L;
    protected List<CachedDataMapZ<T>.KeyInfo> listkey = new ArrayList();

    public CachedDataMapZ() {
    }

    public CachedDataMapZ(int sizelimit) {
        this.sizelimit = sizelimit;
    }

    public CachedDataMapZ(int sizelimit, long deltatime) {
        this.sizelimit = sizelimit;
        this.deltatime = deltatime;
    }

    public T get(String... keys) {
        String key = this.genKey(keys);
        if (!this.validKey(key)) {
            return null;
        }

        return this.mapdata.get(key);
    }

    protected void put(String key, T val) {
        if (this.listkey.size() >= this.sizelimit) {
            CachedDataMapZ<T>.KeyInfo keyinfo = (CachedDataMapZ.KeyInfo)this.listkey.remove(0);
            this.mapdata.remove(keyinfo.name);
        }

        this.listkey.add(new CachedDataMapZ.KeyInfo(key, this.deltatime));
        this.mapdata.put(key, val);
    }

    protected void putAll(Map<String, T> data) {
        Iterator var3 = data.entrySet().iterator();

        while(var3.hasNext()) {
            Entry<String, T> entry = (Entry)var3.next();
            this.put((String)entry.getKey(), entry.getValue());
        }

    }

//    protected abstract T load(String... var1);

    private boolean validKey(String key) {
        this.cleanExpiredKey();
        return this.mapdata.containsKey(key);
    }

    private void cleanExpiredKey() {
        if (this.listkey.size() > 0) {
            while(((CachedDataMapZ.KeyInfo)this.listkey.get(0)).isExpired()) {
                CachedDataMapZ<T>.KeyInfo keyinfo = (CachedDataMapZ.KeyInfo)this.listkey.remove(0);
                this.mapdata.remove(keyinfo.name);
            }
        }

    }

    protected String genKey(String... keys) {
        StringBuffer string = new StringBuffer();
        for(String k : keys){
            string.append(k).append(this.chr);
        }
        return string.toString();
    }

    public void clear() {
        this.listkey.clear();
        this.mapdata.clear();
        log.info("清除缓存:" + this.getClass().getName());
    }

    public void setMyData(T t, String... keys) {
        String key = this.genKey(keys);
        this.put(key, t);
    }

    protected class KeyInfo {
        String name;
        long timeto;

        KeyInfo(String name, long delta) {
            this.name = name;
            this.timeto = System.currentTimeMillis() + delta;
            if (this.timeto < 0L) {
                this.timeto = 9223372036854775807L;
            }

        }

        boolean isExpired() {
            return System.currentTimeMillis() > this.timeto;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/dh1027/article/details/81201242