com.gitee.fufu669.aspect.CacheMockFetchLaterAop Maven / Gradle / Ivy
package com.gitee.fufu669.aspect;
import com.gitee.fufu669.common.CacheKeyCommon;
import com.gitee.fufu669.config.exception.CacheEmptyInstance;
import com.gitee.fufu669.config.exception.CacheServerErrorCode;
import com.gitee.fufu669.config.exception.CacheServerException;
import com.gitee.fufu669.service.CacheService;
import com.gitee.fufu669.utils.CacheAopUtil;
import com.gitee.fufu669.utils.CacheHtmlUtil;
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.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
@Lazy
@Aspect
@Component
/** @author wangfupeng */
public class CacheMockFetchLaterAop {
public static final Logger logger = LoggerFactory.getLogger(CacheMockFetchLaterAop.class);
@Autowired
CacheService cacheService;
@Autowired
@Qualifier(value = "threadPoolTaskExecutorCacheFetchLater")
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Around("@annotation(com.gitee.fufu669.aspect.CacheMockFetchLater)")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
int type = CacheKeyCommon.CACHEMOCKFETCHLATER_TYPE_DEFAULT;
int refreshSeconds = CacheKeyCommon.CACHEFETCHLATERAOP_REFRESH_EXPIRE_SECONDS;
int expireSeconds = CacheKeyCommon.CACHESERVICE_REDIS_DEFAULT_EXPIRED_SECONDS_1_WEEK;
String methodName = null;
String description = "";
try {
String targetName = proceedingJoinPoint.getTarget().getClass().getName();
methodName = proceedingJoinPoint.getSignature().getName();
Object[] arguments = proceedingJoinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
type = method.getAnnotation(CacheMockFetchLater.class).type();
refreshSeconds = method.getAnnotation(CacheMockFetchLater.class).refreshSeconds();
expireSeconds = method.getAnnotation(CacheMockFetchLater.class).expireSeconds();
description = method.getAnnotation(CacheFetchLater.class).description();
break;
}
}
} catch (Exception e) {
logger.info(e.toString());
}
logger.info("%%%%%%CacheMockFetchLaterAop:aroundMethod:description:" + description + "%%%%%%");
String cacheKey = CacheAopUtil.getCacheKey(proceedingJoinPoint);
Object value = cacheService.getValue(cacheKey);
Signature signature = proceedingJoinPoint.getSignature();
Class returnType = ((MethodSignature) signature).getReturnType();
if (value != null) {
boolean refreshFlagMock = CacheAopUtil.isRefreshFlag(refreshSeconds, cacheKey, cacheService);
if (refreshFlagMock) {
lockThenExcecute(proceedingJoinPoint, expireSeconds, cacheKey, description);
}
if (value.getClass().equals(Class.forName("com.gitee.fufu669.config.exception.CacheEmptyInstance"))) {
return null;
}
/*获取当前方法的返回的类名,然后如果是Long类型,碰着值是integer,要强转一哈,否则会报错。*/
value = CacheFetchLaterAop.getValueFromReturnType(value, returnType);
return value;
} else {
lockThenExcecute(proceedingJoinPoint, expireSeconds, cacheKey, description);
if (type == 1) {
throw new CacheServerException(CacheServerErrorCode.CACHEMOCKFETCHLATERAOP_RESULT_NOT_READY);
} else if (type == 2) {
return returnType.newInstance();
} else if (type == 3) {
if (returnType.equals(Class.forName("java.util.List"))) {
return new ArrayList<>();
} else if (returnType.equals(Class.forName("java.util.Map"))) {
return new HashMap();
} else {
return returnType.newInstance();
}
} else {
return null;
}
}
}
public void lockThenExcecute(ProceedingJoinPoint proceedingJoinPoint, int expireSeconds, String cacheKey, String description) {
CustomThreadToRunAndSaveToRedis customThreadToRunAndSaveToRedis = new CustomThreadToRunAndSaveToRedis();
customThreadToRunAndSaveToRedis.setProceedingJoinPoint(proceedingJoinPoint);
customThreadToRunAndSaveToRedis.setExpireSeconds(expireSeconds);
customThreadToRunAndSaveToRedis.setDescription(description);
threadPoolTaskExecutor.execute(customThreadToRunAndSaveToRedis);
}
public class CustomThreadToRunAndSaveToRedis implements Runnable {
private ProceedingJoinPoint proceedingJoinPoint;
private int expireSeconds = CacheKeyCommon.CACHESERVICE_REDIS_DEFAULT_EXPIRED_SECONDS_1_WEEK;
private String description = "";
public void setProceedingJoinPoint(ProceedingJoinPoint proceedingJoinPoint) {
this.proceedingJoinPoint = proceedingJoinPoint;
}
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
public void setDescription(String description) {
this.description = description;
}
public void run() {
String targetName = proceedingJoinPoint.getTarget().getClass().getName();
String methodName = proceedingJoinPoint.getSignature().getName();
logger.info("%%%%%%CacheMockFetchLaterAop:multiThread:☆☆☆start☆☆☆:Classname:" + CacheHtmlUtil.getLastStringSplitHtml(targetName, "\\.") + ":methodName:" + methodName + ":description:" + description + "%%%%%%");
String cacheKey = null;
try {
Object value = null;
try {
value = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
logger.info(throwable.getMessage(), throwable);
}
cacheKey = CacheAopUtil.getCacheKey(proceedingJoinPoint);
if (value == null) {
Signature signature = proceedingJoinPoint.getSignature();
Class returnType = ((MethodSignature) signature).getReturnType();
try {
if (returnType.equals(Class.forName("java.util.List"))) {
cacheService.setValue(cacheKey, new ArrayList<>());
cacheService.expire(cacheKey, expireSeconds);
} else if (returnType.equals(Class.forName("java.util.Map"))) {
cacheService.setValue(cacheKey, new HashMap());
cacheService.expire(cacheKey, expireSeconds);
} else {
if (returnType.isInterface()) {
cacheService.setValue(cacheKey, new CacheEmptyInstance());
cacheService.expire(cacheKey, expireSeconds);
} else {
if (returnType.getName().equals("void")) {
} else {
cacheService.setValue(cacheKey, returnType.newInstance());
cacheService.expire(cacheKey, expireSeconds);
}
}
}
} catch (Exception e) {
logger.info(e.getMessage(), e);
cacheService.setValue(cacheKey, new CacheEmptyInstance());
cacheService.expire(cacheKey, expireSeconds);
}
} else {
cacheService.setValue(cacheKey, value);
cacheService.expire(cacheKey, expireSeconds);
}
} catch (Exception e) {
logger.info(e.getMessage(), e);
} finally {
cacheService.unlock(CacheKeyCommon.LOCK + cacheKey);
logger.info("%%%%%%CacheMockFetchLaterAop:multiThread:★★★end★★★:Classname:" + CacheHtmlUtil.getLastStringSplitHtml(targetName, "\\.") + ":methodName:" + methodName +":description:" + description + "%%%%%%");
}
}
}
}