@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Cache {
//缓存多少秒,默认无限期
public int expire() default 0;
}
package ***;
import com.alibaba.fastjson.JSON;
***
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @Author seventeen
* @Version 1.0
* @Date 2018/9/11.
* 这世界太拥挤,做开发太累,所以需要用缓存的时候方法上加个@Cache就好了(目前只支持基本数据类型参数)
*/
@Component
@Aspect
public class CacheAspect {
public static final Logger logger = Logger.getLogger(CacheAspect.class);
@Autowired
private RedisCacheClient redis;
/**
* 定义分隔符
*/
private static final String DELIMITER = ":";
/**
* 定义锁后缀
*/
private static final String LOCKSTR = "_LOCKSTR";
@Pointcut("@annotation(***.redis.Cache)")
public void cachePointcut() {
}
@Around("cachePointcut()")
public Object RedisCache(final ProceedingJoinPoint joinPoint)
throws Throwable {
String clazzName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
String key = getKey(clazzName, methodName, args);
if (logger.isInfoEnabled()) {
logger.info("生成key: " + key);
}
Object value = getCachedData(key);
Object result = null;
if (null == value) {
// 缓存未命中
if (logger.isDebugEnabled()) {
logger.debug("缓存未命中");
}
// 调用数据库查询方法
synchronized (key + LOCKSTR) {
value = getCachedData(key);
if (null == value) {
result = joinPoint.proceed(args);
}
}
// 序列化查询结果
final String jsonResult = serialize(result);
final int keyExpire = getKeyExpire(joinPoint);
if (keyExpire == 0) {
redis.set(key, jsonResult);
} else {
redis.set(key, jsonResult, Long.valueOf(keyExpire));
}
return result;
}
if (logger.isDebugEnabled()) {
logger.debug("缓存命中, value = " + value);
}
result = JSON.parse((String) value);
if (logger.isDebugEnabled()) {
logger.debug("反序列化结果 = {}" + result);
}
return result;
}
private int getKeyExpire(ProceedingJoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Class clazz = targetMethod.getClass();
Cache cache = targetMethod.getAnnotation(Cache.class);
int expire = cache.expire();
return expire;
}
private Object getCachedData(String key) {
Object value = redis.get(key);
if (null == value) {
value = redis.get(key);
}
return value;
}
private String getKey(String clazzName, String methodName, Object[] args) {
StringBuilder key = new StringBuilder(SOPConstants.REDIS_SOP);
key.append(clazzName);
key.append(DELIMITER);
key.append(methodName);
key.append(DELIMITER);
if (args.length > 0) {
for (Object obj : args) {
if (obj != null) {
key.append(obj.toString());
key.append(DELIMITER);
}
}
}
return key.toString();
}
protected String serialize(Object target) {
if (target == null) {
return "";
}
return JSON.toJSONString(target);
}
}