基于AOP的缓存

在实际的开发框架中,需要用到缓存,很多时候,我们的缓存是基于ORM框架的缓存,使用起来不能满足实际情况

目前我们的开发是按照接口来开发的,需要在service 层就使用缓存,如CMS中的文章等等。故我们设计了基于AOP的缓存框架

不多说,直接贴代码

annotation:

package com.lsxin.framework.annotation;

import com.lsxin.framework.annotation.constant.CacheExpirationTime;
import com.lsxin.framework.annotation.constant.CacheType;

import java.lang.annotation.*;

/**
 * ***************************************************************
 * <pre>
 * Copyright (c) 2016 –苏州利盛欣信息科技有限公司
 *  Title: com.lsxin.framwork.annotation
 *  Description:
 *  History:
 * <p> 2016/3/21 init</p>
 * ***************************************************************
 *  2016/3/21   V1.0  guzhixiong    New Files for framework
 * </pre>
 */
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LsxCache {
    /**
     * 缓存类型
     * @return
     */
    CacheType cacheType() default CacheType.CACHE;

    /**
     * 缓存名称
     * @return
     */
    String cacheName();

    /**
     * 过期时间
     * @return
     */
    CacheExpirationTime expirationTime() default CacheExpirationTime.ONE_DAY;
}

缓存Aop 缓存的AOP是基于Annotation的

package com.lsxin.framework.support.spring;

import com.alibaba.fastjson.JSON;
import com.lsxin.framework.annotation.LsxCache;
import com.lsxin.framework.annotation.constant.CacheType;
import com.lsxin.framework.cache.LsxCacheManager;
import com.lsxin.framework.log.LsxLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * ***************************************************************
 * <pre>
 * Copyright (c) 2016 –苏州利盛欣信息科技有限公司
 *  Title: com.lsxin.framework.support.spring
 *  Description:缓存拦截Aop
 *  History:
 * <p> 2016/3/24 init</p>
 * ***************************************************************
 *  2016/3/24   V1.0  guzhixiong    New Files for framework
 * </pre>
 */
@Aspect
public class CacheAop {
    private LsxLog log = LsxLog.getInstance(MethodAop.class,"framework");
    // 缓存
    @Autowired(required = false)
    private LsxCacheManager cacheManager;
    @Pointcut("@annotation(com.lsxin.framework.annotation.LsxCache)")
    public void cachePointcut() {
    }
    @Around("cachePointcut()&& @annotation(lsxCache)")
    public Object aroundMethod(ProceedingJoinPoint joinPoint,LsxCache lsxCache) throws Throwable {
        //原方法名
        String methodName = joinPoint.getSignature().getName();
        if(lsxCache !=null){
            if (lsxCache.cacheType().equals(CacheType.CACHE)) {
                Object[] arguments = joinPoint.getArgs();
                String cacheKey = getCacheKey(lsxCache.cacheName(), methodName, arguments);
                Object data = cacheManager.get(lsxCache.cacheName(),cacheKey);
                if(data==null){
                    data = joinPoint.proceed();
                    cacheManager.set(lsxCache.cacheName(),cacheKey,data);
                }
                log.i("{} use cache: {} ",methodName,lsxCache.cacheName());
                return data;
            }
            if(lsxCache.cacheType().equals(CacheType.CACHE_UPDATE)){
                cacheManager.clear(lsxCache.cacheName());
                log.i("{} clear cache: {}",methodName,lsxCache.cacheName());
            }
        }
        return joinPoint.proceed();
    }

    private String getCacheKey(String className, String methodName, Object[] arguments) {
        StringBuffer sb = new StringBuffer();
        sb.append(className).append(".").append(methodName);
        if ((arguments != null) && (arguments.length != 0)) {
            for (int i = 0; i < arguments.length; i++) {
                sb.append(".").append(JSON.toJSONString(arguments[i]));
            }
        }
        return sb.toString();
    }

    public void setCacheManager(LsxCacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }
}

Cache 接口类,在开发中,我们可以根据不同的情况实现不同的缓存(redis mongodb等) 即可

package com.lsxin.framework.cache;

import java.util.List;

/**
 * ***************************************************************
 * <pre>
 * Copyright (c) 2016 –苏州利盛欣信息科技有限公司
 *  Title: com.lsxin.framwork.cache
 *  Description:缓存接口
 *  History:
 * <p> 2016/3/22 init</p>
 * ***************************************************************
 *  2016/3/22   V1.0  guzhixiong    New Files for framework
 * </pre>
 */
public interface LsxCacheManager {
    /**
     * 设置缓存
     * @param name
     * @param key
     * @param value
     */
    public void set(String name, Object key, Object value) throws CacheException;

    /**
     * 获取缓存
     * @param name
     * @param key
     * @return
     */
    public Object get(String name,Object key) throws CacheException;

    /**
     * 获取缓存
     * @param resultClass
     * @param name
     * @param key
     * @param <T>
     * @return
     */
    public <T> T get(Class<T> resultClass, String name, Object key) throws CacheException;

    /**
     * 删除一个数据
     * @param name
     * @param key
     */
    public void  delete(String name, Object key) throws CacheException;

    /**
     * 批量删除
     * @param name
     * @param keys
     */
    public void batchDelete(String name,List keys) throws CacheException;

    /**
     * 清空数据
     * @param name
     */
    public void clear(String name) throws CacheException;

    /**
     * 获取所有的缓存键值
     * @param name
     * @return
     * @throws CacheException
     */
    public List keys(String name) throws CacheException;
}

使用:

 在使用的时候,只需要配置aop 如下图

101048_c6Mk_100018.png

在实际使用中只需要在对应的代码上面只需要打上cache 的注解即可,是不是很方便

101257_y3dr_100018.png

转载于:https://my.oschina.net/guzhixiong/blog/703166

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值