aop+反射:ログカット(listおよびその他のタイプの値を取得)


1:役割
       1.取得方法のあるパラメータの属性の値(戻り値タイプは不確定で、必要なパラメータはオブジェクト内の位置が不確定)
2:例を挙げる
        需要:操作ログを記録し、ユーザーが注文を削除したり、物品を購入したりする操作を保存する。
    2.1:コメント
/**
*       
* @Auther: ZhangSuchao
* @Date: 2020/7/29 21:02
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SaveLog {

  //      (  ) id  
  String idsName() default "";

  //     
  int operatorKind() default 0;

  //     (          ,    )
  String remarkName() default "";
}
    2.2:要求エンティティ類
import lombok.Data;

/**
* @Auther: ZhangSuchao
* @Date: 2020/7/29 20:02
*/
@Data
public class OrderDTO {

   //   s
   private Integer ids;

   //   
   private String remark;
}
    2.3:サービスの方法
    /**
     *     
     *
     * @param orderDTO
     */
    @SaveLog(idsName = "orderDTO-ids", remarkName = "orderDTO-remark", operatorKind = 1)
    public void delOrders(OrderDTO orderDTO) {

        // TODO: 2020/7/29       
    }
    /**
     *     
     *
     * @param orderId   id
     */
    @SaveLog(idsName = "orderId", operatorKind = 2)
    public void buyGoods(Integer orderId) {
        // TODO: 2020/7/29     
    }
    2.4:目的
2.3のdelOrdersメソッドのidsとremarkを取得しても、buyGoodsのordedersIdを取得します。
3:うどん
/**
 *     
 *
 * @Auther: ZhangSuchao
 * @Date: 2020/7/29 19:38
 */
@Aspect
@Component
public class LogAspect {

    @Pointcut(value = "@annotation(com.draymond.aop.annotation.SaveLog)")
    public void logPoint() {

    }

    @AfterReturning(value = "logPoint()")
    public void saveLog(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SaveLog saveLog = method.getAnnotation(SaveLog.class);
        if (saveLog == null) {
            return;
        }
        //       
        String[] paraNames = signature.getParameterNames();
        //     
        Object[] paraValues = joinPoint.getArgs();

        //   :idsName       Integer,    List
        String idsName = saveLog.idsName();
        int operatorKind = saveLog.operatorKind();
        String remarkName = saveLog.remarkName();

        //     Integer/List   :   idsName        ,           (       )
        Object object = ReflectUtils.getValueByParaName(idsName, paraNames, paraValues);

        //     String
        String remark = ReflectUtils.getValueByParaName(idsName, paraNames, paraValues);


        //             
        List idsList = ReflectUtils.parse2IntList(object);
        // todo           
    }
}
4:反射工具類
ここでは汎型を使いますが、受信パラメータの値は共通です。
package com.draymond.aop.spring.aspect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 *      
 *
 * @Auther: ZhangSuchao
 * @Date: 2020/7/29 20:18
 */
public class ReflectUtils {


    /**
     *    idsName   paraValues         
     *
     * @param paraName
     * @param paraNames
     * @param paraValues
     * @param 
     * @return
     */
    public static  T getValueByParaName(String paraName, String[] paraNames, Object[] paraValues) {

        String[] paraNameSplit = paraName.split("-");
        int paraNameLength = paraNameSplit.length;
        if (paraNameSplit.length == 0) {
            return null;
        }

        //        (orderDTO-ids   orderDTO  )
        int index = ReflectUtils.getIndex(paraNameSplit[0], paraNames);

        if (index < 0) {
            return null;
        }
        Object object = ReflectUtils.getValue(index, paraValues);

        Object tempObj = object;

        try {


            for (int i = 0; i < paraNameLength - 1; i++) {

                Class> clz = object.getClass();
                Field paraField = clz.getDeclaredField(paraNameSplit[i + 1]);
                paraField.setAccessible(true);

                // Integet String...     
                if (Integer.class.isAssignableFrom(paraField.getType()) || String.class.isAssignableFrom(paraField.getType())) {
                    tempObj = paraField.get(object);
                }
                //     
                else if (List.class.isAssignableFrom(paraField.getType())) {
                    tempObj = ReflectUtils.getList(paraField, tempObj);

                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return (T) tempObj;
    }

    /**
     *     list  
     *
     * @param paraField         
     * @param tempObj     
     * @param 
     * @return
     */
    /**
     *         list  
     *
     * @param object
     */
    public static  List getList(Field field, Object object) {
        List resultList = new ArrayList<>();
        if (object != null) {
            try {
                Class clzz = field.get(object).getClass();
                //       list size           
                Method sizeMethod = clzz.getDeclaredMethod("size");
                if (!sizeMethod.isAccessible()) {
                    sizeMethod.setAccessible(true);
                }
                //    
                int size = (int) sizeMethod.invoke(field.get(object));
                //         
                for (int i = 0; i < size; i++) {
                    //     list get  
                    Method getMethod = clzz.getDeclaredMethod("get", int.class);
                    //  get      
                    if (!getMethod.isAccessible()) {
                        getMethod.setAccessible(true);
                    }

                    Object invoke = getMethod.invoke(field.get(object), i);
                    T var1 = (T) invoke;
                    resultList.add(var1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    /**
     *        
     *
     * @param index
     * @param paraValues
     * @return
     */
    private static Object getValue(int index, Object[] paraValues) {
        return (index >= 0 && paraValues.length > index) ? paraValues[index] : null;
    }

    /**
     *    paraName   paraNames       
     *
     * @param paraName
     * @param paraNames
     * @return
     */
    private static int getIndex(String paraName, String[] paraNames) {

        for (int i = 0; i < paraNames.length; i++) {
            if (paraName.equals(paraNames[i])) {
                return i;
            }
        }
        return -1;

    }

    /**
     *  object   List
     *
     * @param object
     * @return
     */
    public static List parse2IntList(Object object) {
        List list = new ArrayList<>();

        if (object instanceof Integer) {
            list.add((Integer) object);
        } else if (object instanceof List) {
            //       object  List         
            list = (List) object;
        }
        return list;
    }
}
湖南省の備考:
長所
  • 反射により、任意のオブジェクトの属性値を取得することができます。属性の位置がどんなに深いかにかかわらず、(エルゴードによって取得された値:ordented-indsによって、idsの値を取得します。)
  • 汎型を使用して、値を取得する結果のタイプは、実際の状況に応じて変化することができます。(1)。(1)中間層であれば、
  • をさらに処理する必要があります。
    3.重点方法(いずれも汎型を使う)
    パラメータに対応する値を取得するpublic static T getValueByParaName(String paraName, String[] paraNames, Object[] paraValues)は、リストpublic static List getList(Field field, Object object)を取得する。