使用自定義註解+AOP實現存放HASH類型的Redis緩存
1.自定義的Redis方法
public Object hget(String key, String hashKey) {
return redisTemplate.opsForHash().get(key, hashKey);
}
public <T> T hget(String key, String hashKey, Class<T> clazz) {
Object hget = hget(key, hashKey);
if (ConvertUtils.isEmpty(hget)){
return null;
}
if (clazz.isInstance(hget)){
return clazz.cast(hget);
}
return null;
}
2.自定義註解
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HashCache {
String hashIdentification();
String hashKey();
int expireTime() default -2;
}
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HashCacheEvict {
String hashIdentification();
String hashKey();
}
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HashCachePut {
String hashIdentification();
String hashKey();
int expireTime() default -2;
}
3.自定義Aspect
import com.zzdz.platform.base.annotation.HashCache;
import com.zzdz.platform.base.annotation.HashCacheEvict;
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.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.lang.reflect.Method;
@Aspect
@Component
public class HashCacheAspect {
@Resource
private com.zzdz.platform.base.util.RedisUtil redisUtil;
private Method getMethod(ProceedingJoinPoint proceedingJoinPoint) {
Object[] args = proceedingJoinPoint.getArgs();
Class[] argTypes = new Class[proceedingJoinPoint.getArgs().length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
Method method = null;
try {
method = proceedingJoinPoint.getTarget().getClass().getMethod(proceedingJoinPoint.getSignature().getName(), argTypes);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return method;
}
private String parseKey(String hashKey, Method method, Object[] args) {
LocalVariableTableParameterNameDiscoverer localVariableTableParameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
String[] paraNameArr = localVariableTableParameterNameDiscoverer.getParameterNames(method);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < paraNameArr.length; i++) {
context.setVariable(paraNameArr[i], args[i]);
}
return parser.parseExpression(hashKey).getValue(context, String.class);
}
@Around("@annotation(com.zzdz.platform.base.annotation.HashCache)")
public Object hashCache(ProceedingJoinPoint proceedingJoinPoint) {
Method method = getMethod(proceedingJoinPoint);
HashCache hashCache = method.getAnnotation(HashCache.class);
String hashIdentification = hashCache.hashIdentification();
String hashKey = parseKey(hashCache.hashKey(), method, proceedingJoinPoint.getArgs());
int expireTime = hashCache.expireTime();
Class returnType = ((MethodSignature) proceedingJoinPoint.getSignature()).getReturnType();
Object result = redisUtil.hget(hashIdentification, hashKey, returnType);
if (result == null){
try {
result = proceedingJoinPoint.proceed();
Assert.notNull(hashKey, "HASH內存放的Key");
if (expireTime >= 0){
redisUtil.hset(hashIdentification, hashKey, result, expireTime);
}else {
redisUtil.hset(hashIdentification, hashKey, result);
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
return result;
}
@Around("@annotation(com.zzdz.platform.base.annotation.HashCacheEvict)")
public void hashCacheEvict(ProceedingJoinPoint proceedingJoinPoint) {
Method method = getMethod(proceedingJoinPoint);
HashCacheEvict hashCacheEvict = method.getAnnotation(HashCacheEvict.class);
String hashIdentification = hashCacheEvict.hashIdentification();
String hashKey = hashCacheEvict.hashKey();
Class returnType = ((MethodSignature) proceedingJoinPoint.getSignature()).getReturnType();
Object result = redisUtil.hget(hashIdentification, hashKey);
if (result == null){
return;
}
redisUtil.del(hashIdentification, hashKey);
}
@Around("@annotation(com.zzdz.platform.base.annotation.HashCachePut)")
public Object hashCachePut(ProceedingJoinPoint proceedingJoinPoint) {
Method method = getMethod(proceedingJoinPoint);
HashCache hashCache = method.getAnnotation(HashCache.class);
String hashIdentification = hashCache.hashIdentification();
String hashKey = parseKey(hashCache.hashKey(), method, proceedingJoinPoint.getArgs());
int expireTime = hashCache.expireTime();
Object result = null;
try {
result = proceedingJoinPoint.proceed();
Assert.notNull(hashKey, "HASH內存放的Key");
if (expireTime >= 0){
redisUtil.hset(hashIdentification, hashKey, result, expireTime);
}else {
redisUtil.hset(hashIdentification, hashKey, result);
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return result;
}
}