SpringBoot 使用@Aspect進行日誌管理(基於反射代理模式+動態修改註解Log)

在上一篇「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…數組

相關文章
相關標籤/搜索