AOP實踐-日誌記錄
阿新 • • 發佈:2018-12-18
AOP實踐-自定義註解實現日誌記錄 專案環境springboot spring AOP預設是使用AspectJ的註解 https://www.eclipse.org/aspectj/
1.引入jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.自定義註解
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MethodLog { String remark() default ""; int operType() default 0; }
3.日誌記錄 此處每次操作完成之後記錄日誌
@Component @Aspect public class LogService { @Autowired OperateLogMapper operateLogMapper; /** * 切點 */ @Pointcut("@annotation(com.cmft.basic.aspect.annotation.MethodLog)") public void methodCachePointcut() { } @AfterThrowing("methodCachePointcut()") public void test(JoinPoint point) { } /** * 切面 * * @param point * @return * @throws Throwable */ @AfterReturning("methodCachePointcut()") public void recordOperateLog(JoinPoint point) throws Throwable { Map<String, Object> methodMap = getMthodMap(point); String packages = point.getThis().getClass().getName(); if (packages.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB動態生成的類 packages = packages.substring(0, packages.indexOf("$$")); return; } Object[] methodParam = null; methodParam = point.getArgs(); // 獲取方法引數 Map<String, Object> parMap = objectToMap(methodParam[0]); // 記錄日誌 //... operateLog.setRemark(String.valueOf(methodMap.get("remark"))); operateLog.setTypeId((Integer)methodMap.get("operType")); //... } /** * 獲取利用反射獲取類裡面的值和名稱 * * @param obj * @return * @throws IllegalAccessException */ public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException { Map<String, Object> map = new HashMap<>(); Class<?> clazz = obj.getClass(); if (clazz.isPrimitive() || clazz.getName().equals("java.lang.String")) { map.put("id", obj); return map; } for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); String fieldName = field.getName(); Object value = field.get(obj); map.put(fieldName, value); } return map; } /** * 獲取方法中的中文備註 * * @param joinPoint * @return * @throws Exception */ public static Map<String, Object> getMthodMap(JoinPoint joinPoint) throws Exception { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class<?> targetClass = Class.forName(targetName); Method[] method = targetClass.getMethods(); Map<String, Object> methodMap = new HashMap<String, Object>(); for (Method m : method) { if (m.getName().equals(methodName)) { @SuppressWarnings("rawtypes") Class[] tmpCs = m.getParameterTypes(); if (tmpCs.length == arguments.length) { MethodLog methodCache = m.getAnnotation(MethodLog.class); if (methodCache != null) { int operType = methodCache.operType(); String remark = methodCache.remark(); methodMap.put("operType", operType); methodMap.put("remark", remark); } break; } } } return methodMap; } }
4.使用 AOP必須基於介面實現,所以在介面實現類的方法上加入如下註解即可
@MethodLog(remark = "更新", operType = Constant.APPROVE)