在上一篇「SpringBoot 使用@Aspect進行日誌管理(基於反射代理模式+註解Log)」的基礎上,添加註解進行日誌管理升級版
一、修改日誌註解類java
/**
* 日誌註解
* Created by 陳梓平 on 2017/9/7.
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JournalLog {
/** 要執行的操做類型好比:add **/
int operationType() default -1;
/** 要執行的模塊名稱如:Carouse **/
int modularTypeName() default -1;
/**註解說明*/
String xplain() default "";
/**判斷類型*/
boolean checkBoolean() default false;
/**註解說明數組*/
String[] xplainArray() default "";
}複製代碼
二、添加註解工具類git
/**
* 註解工具類
* Created by 陳梓平 on 2017/9/11.
*/
public class AnnotationUtils {
/**日誌輸出*/
private static final Logger logger = LoggerFactory.getLogger(AnnotationUtils.class);
private static AnnotationUtils mInstance;
public AnnotationUtils() {
}
public static AnnotationUtils get() {
if (mInstance == null) {
synchronized (AnnotationUtils.class) {
if (mInstance == null) {
mInstance = new AnnotationUtils();
}
}
}
return mInstance;
}
/**
* 獲取註解屬性值信息
* @param className 類名
* @param methodName 方法名
* @param annotationClass 註解類
* @param attrName 註解屬性名
* @throws NotFoundException
*/
public static Object getAnnotationAttr(String className,String methodName,Class<?> annotationClass,String attrName) throws NotFoundException, NoSuchMethodException {
Object value = null;
if (StringUtils.isBlank(className))
return value;
if (StringUtils.isBlank(methodName))
return value;
if (annotationClass==null)
return value;
if (StringUtils.isBlank(attrName))
return value;
ClassPool pool = ClassPool.getDefault();
//獲取要修改的類的全部信息
CtClass ct = pool.get(className);
CtMethod ctMethod = ct.getDeclaredMethod(methodName);
MethodInfo methodInfo = ctMethod.getMethodInfo();
//獲取註解屬性
AnnotationsAttribute attribute = (AnnotationsAttribute) methodInfo.getAttribute(AnnotationsAttribute.visibleTag);
String annotationName = annotationClass.getName();
Method operationType = annotationClass.getDeclaredMethod(attrName);
Class<?> returnType = operationType.getReturnType();
if (attribute!=null){
//獲取註解
Annotation annotation = attribute.getAnnotation(annotationName);
if (annotation!=null){
//獲取註解的值
if (int.class.isAssignableFrom(returnType)){
IntegerMemberValue memberValue = (IntegerMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue.getValue() ;
}
if (String.class.isAssignableFrom(returnType)){
StringMemberValue memberValue = (StringMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue .getValue() ;
}
if (boolean.class.isAssignableFrom(returnType)){
BooleanMemberValue memberValue = (BooleanMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue.getValue() ;
}
if (String[].class.isAssignableFrom(returnType)){
ArrayMemberValue memberValue = (ArrayMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null){
MemberValue[] strValueArray = memberValue.getValue();
String[] strValueA = new String[strValueArray.length];
for (int i = 0;i<strValueArray.length;i++){
StringMemberValue stringMemberValue = (StringMemberValue) strValueArray[i];
strValueA[i] = stringMemberValue.getValue();
}
value = strValueA;
}
}
}
}
return value;
}
/**
* 修改註解屬性
* @param className 類名
* @param methodName 方法名
* @param annotationClass 註解名
* @param attrName 屬性名
* @param value 修改值
* @throws NotFoundException
*/
public static boolean updateAnnotationAttr(String className,String methodName,Class<?> annotationClass,String attrName,Object value) throws NotFoundException, NoSuchMethodException {
if (StringUtils.isBlank(className))
return false;
if (StringUtils.isBlank(methodName))
return false;
if (annotationClass==null)
return false;
if (StringUtils.isBlank(attrName))
return false;
if (value==null)
return false;
ClassPool pool = ClassPool.getDefault();
//獲取須要修改的類
CtClass ct = pool.get(className);
CtMethod minInfo = ct.getDeclaredMethod(methodName);
MethodInfo methodInfo = minInfo.getMethodInfo();
ConstPool cp = methodInfo.getConstPool();
AnnotationsAttribute attribute = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
String annotationName = annotationClass.getName();
Method operationType = annotationClass.getDeclaredMethod(attrName);
Class<?> returnType = operationType.getReturnType();
Annotation annotation = new Annotation(annotationName, cp);
//修更名稱爲unitName的註解
if (annotation != null) {
if (String.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new StringMemberValue((String) value, cp));
else if (int.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new IntegerMemberValue(cp,(Integer)value));
else if (boolean.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new BooleanMemberValue((boolean) value, cp));
else if (String[].class.isAssignableFrom(returnType)){
String[] stres = (String[])value;
StringMemberValue[] elements = new StringMemberValue[stres.length];
for(int i=0;i<stres.length;i++)
elements[i] = new StringMemberValue(stres[i],cp);
ArrayMemberValue amv = new ArrayMemberValue(cp);
amv.setValue(elements);
annotation.addMemberValue(attrName,amv);
}else
return false;
attribute.setAnnotation(annotation);
methodInfo.addAttribute(attribute);
return true;
}
return false;
}
}複製代碼
三、修改日誌切面類spring
import com.chen.annotation.JournalLog;
import com.chen.exception.CustomException;
import com.chen.staticInfos.StaticInfo;
import com.chen.utils.AnnotationUtils;
import com.chen.utils.JournalUtils;
import javassist.NotFoundException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* 日誌切面
* Created by 陳梓平 on 2017/9/11.
*/
@Component
@Aspect
public class JournalAspect {
/**日誌輸出*/
private static final Logger logger = LoggerFactory.getLogger(JournalAspect.class);
/**日誌工具類*/
@Autowired
private JournalUtils aspectJournalUtils;
/**service層切面*/
private final String POINT_CUT = "execution(* com.chen.service..*(..))";
@Pointcut(POINT_CUT)
private void pointcut(){}
/**
* 後置最終通知(目標方法只要執行完了就會執行後置通知方法)
* 日誌管理
* @param joinPoint
*/
@After(value = "pointcut()")
@Transactional
public void doAfterAdvice(JoinPoint joinPoint) throws CustomException, ClassNotFoundException, NotFoundException, NoSuchMethodException {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
int modulerType = -1;
int opreationType = -1;
modulerType = (int) AnnotationUtils.get().getAnnotationAttr(className, methodName, JournalLog.class, StaticInfo.AOP_LOG_ATTR_NAME1);
opreationType = (int) AnnotationUtils.get().getAnnotationAttr(className, methodName, JournalLog.class, StaticInfo.AOP_LOG_ATTR_NAME2);
//3.添加日誌
if (modulerType!=-1&&opreationType!=-1)
//TODO 3.1 從請求獲取用戶id
aspectJournalUtils.addJournalInfo(modulerType,opreationType, 10086);
}
}複製代碼
代碼連接:git.oschina.net/CatalpaFlat…數組