1 package com.example.aspect; 2 3 import com.google.common.collect.Maps; 4 import org.apache.commons.lang3.ArrayUtils; 5 import org.apache.commons.lang3.builder.ToStringBuilder; 6 import org.apache.commons.lang3.builder.ToStringStyle; 7 import org.aspectj.lang.ProceedingJoinPoint; 8 import org.aspectj.lang.annotation.*; 9 import org.aspectj.lang.reflect.MethodSignature; 10 import org.slf4j.Logger; 11 import org.slf4j.LoggerFactory; 12 import org.springframework.stereotype.Component; 13 import org.springframework.web.multipart.MultipartFile; 14 15 import java.lang.reflect.Method; 16 import java.sql.Time; 17 import java.sql.Timestamp; 18 import java.util.*; 19 20 /** 21 * 日志切面 22 * 23 * @author mingtian 24 */ 25 @Aspect 26 @Component 27 public class WorkFlowLogAspect { 28 29 /** 30 * 打印日志 31 */ 32 private final Logger logger = LoggerFactory.getLogger(WorkFlowLogAspect.class); 33 34 private static Map<Class, Class> primitiveMap = Maps.newHashMap(); 35 36 static { 37 primitiveMap.put(Boolean.class, Boolean.TYPE); 38 primitiveMap.put(Byte.class, Byte.TYPE); 39 primitiveMap.put(Character.class, Character.TYPE); 40 primitiveMap.put(Short.class, Short.TYPE); 41 primitiveMap.put(Integer.class, Integer.TYPE); 42 primitiveMap.put(Long.class, Long.TYPE); 43 primitiveMap.put(Float.class, Float.TYPE); 44 primitiveMap.put(Double.class, Double.TYPE); 45 primitiveMap.put(String.class, String.class); 46 primitiveMap.put(Calendar.class, Calendar.class); 47 primitiveMap.put(Date.class, Date.class); 48 primitiveMap.put(java.sql.Date.class, java.sql.Date.class); 49 primitiveMap.put(Timestamp.class, Timestamp.class); 50 primitiveMap.put(Time.class, Time.class); 51 } 52 53 54 /** 55 * 日志处理 56 * 57 * @param joinPoint 58 * @return 59 * @throws Throwable 60 */ 61 @Around(value = "execution(* com.example.web.controller..*(..))" + " || execution(* com.example.service..*(..))") 62 public Object around(ProceedingJoinPoint joinPoint) throws Throwable { 63 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); 64 Method method = methodSignature.getMethod(); 65 String fullMethodName = joinPoint.getTarget().getClass().getName() + "." + method.getName(); 66 Object[] args = joinPoint.getArgs(); 67 68 Object result = null; 69 long startTime = Calendar.getInstance().getTimeInMillis(); 70 logger.info(">>>>>>>>>>>>>>> access method:{} params:{}", fullMethodName, appendArgs(methodSignature, args)); 71 try { 72 result = joinPoint.proceed(args); 73 long endTime = Calendar.getInstance().getTimeInMillis(); 74 logger.info("<<<<<<<<<<<<<< success method:{} 耗时:{}毫秒", fullMethodName, (endTime - startTime)); 75 return result; 76 } catch (Throwable e) { 77 long endTime = Calendar.getInstance().getTimeInMillis(); 78 logger.error("<<<<<<<<<<<<<< error method:{} 耗时:{}毫秒", fullMethodName, (endTime - startTime), e); 79 throw e; 80 } 81 } 82 83 84 private String appendArgs(MethodSignature methodSignature, Object[] args) { 85 StringBuilder stringBuilder = new StringBuilder(); 86 String[] parameterNames = methodSignature.getParameterNames(); 87 Class[] classes = methodSignature.getParameterTypes(); 88 if (ArrayUtils.isEmpty(parameterNames)) { 89 return stringBuilder.toString(); 90 } 91 int size = Math.min(ArrayUtils.getLength(parameterNames), ArrayUtils.getLength(args)); 92 stringBuilder.append("{"); 93 for (int i = 0; i < size; i++) { 94 if (isFile(classes[i])) { 95 continue; 96 } 97 stringBuilder.append(parameterNames[i]).append("="); 98 if (args[i] != null) { 99 if (isPrimitive(args[i].getClass())) { 100 stringBuilder.append(args[i]); 101 } else { 102 if (List.class.isAssignableFrom(classes[i])) { 103 List tempCollection = (List) args[i]; 104 Object[] tempArray = tempCollection.toArray(); 105 stringBuilder.append(ToStringBuilder.reflectionToString(tempArray, ToStringStyle.SHORT_PREFIX_STYLE)); 106 } else { 107 stringBuilder.append(ToStringBuilder.reflectionToString(args[i], ToStringStyle.SHORT_PREFIX_STYLE)); 108 } 109 } 110 } else { 111 stringBuilder.append("null"); 112 } 113 if (i != size - 1) { 114 stringBuilder.append(","); 115 } 116 } 117 stringBuilder.append("}"); 118 return stringBuilder.toString(); 119 } 120 121 /** 122 * 对于包装类 String类型 日期类型 以及number的子类型 123 * 124 * @param clazz 125 * @return 126 */ 127 private boolean isPrimitive(Class clazz) { 128 if (clazz.isPrimitive() || primitiveMap.containsKey(clazz)) { 129 return true; 130 } 131 if (Number.class.isAssignableFrom(clazz)) { 132 return true; 133 } 134 return false; 135 } 136 137 /** 138 * 文件上传字段不打印 139 * 140 * @param clazz 141 * @return 142 */ 143 private boolean isFile(Class clazz) { 144 if (MultipartFile.class.isAssignableFrom(clazz)) { 145 return true; 146 } 147 if ((clazz.isArray()) && (MultipartFile.class.isAssignableFrom(clazz.getComponentType()))) { 148 return true; 149 } 150 return false; 151 } 152 153 }