通過自定義注解調用方法執行日志存儲:
package com.zktx.platform.log2; import java.lang.reflect.Method; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; 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.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.zktx.platform.entity.tb.logInfo; import com.zktx.platform.entity.tb.user.ShiroUser; import com.zktx.platform.service.log.LogService; import com.zktx.platform.shiro.SecurityUtils; /** * * 首先我們為什么需要做日志管理,在現實的上線中我們經常會遇到系統出現異常或者問題。 這個時候就馬上打開CRT或者SSH連上服務器拿日子來分析。 * 受網絡的各種限制。於是我們就想為什么不能直接在管理后台查看報錯的信息呢。於是日志管理就出現了。 * 其次個人覺得做日志管理最好的是Aop,有的人也喜歡用攔截器。都可以,在此我重點介紹我的實現方式。 Aop有的人說攔截不到Controller。 * 有的人說想攔AnnotationMethodHandlerAdapter截到Controller必須得攔截org * .springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter。 * 首先Aop可以攔截到Controller的 * ,這個是毋容置疑的其次須攔截AnnotationMethodHandlerAdapter也不是必須的。最起碼我沒有驗證成功過這個 * 。我的Spring版本是4.0.3。 * Aop之所以有的人說攔截不到Controller是因為Controller被jdk代理了。我們只要把它交給cglib代理就可以了 * * <!-- 啟動對@AspectJ注解的支持 --> <aop:aspectj-autoproxy /> * <!--通知spring使用cglib而不是jdk的來生成代理方法 AOP可以攔截到Controller--> * <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> * <!-- 節點中proxy-target-class="true"不為true時。 * * 當登錄的時候會報這個異常java.lang.NoSuchMethodException: $Proxy54.login(), --> * <aop:config proxy-target-class="true"></aop:config> * * 創建一個切點類 * * @author Administrator * */ @Aspect @Component public class SystemLogAspect { // 本地異常日志記錄對象 private static final Logger log = LoggerFactory.getLogger(SystemLogAspect.class); @Autowired LogService logService; @Autowired private HttpServletRequest request; // Controller層切點 @Pointcut("@annotation(com.zktx.platform.log2.SystemControllerLog)") public void controllerAspect() { } @After(value = "controllerAspect()") public void doAfter(JoinPoint joinPoint) { // 這里獲取request;千萬不要寫在下邊的線程里,因為得不到 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); System.out.println(request.getAttribute("message") + "======="); new Thread(new Runnable() { @Override public void run() { try { // log.info("進入日志系統————————————" + request.getLocalAddr()); logInfo info = new logInfo(); String description = getControllerMethodDescription(joinPoint); ShiroUser user = SecurityUtils.getShiroUser(); info.setUser_name(user.getName()); info.setMessage(description); info.setIp_address(user.getIpAddress()); info.setCreate_time(new Date()); logService.insertLogInfo(info); } catch (Exception e) { e.printStackTrace(); } } }).start(); } // 可以得到方法return的值 @AfterReturning(returning = "ret", pointcut = "controllerAspect()") public void doAfterReturning(Object ret) throws Throwable { // 處理完請求,返回內容 System.out.println(ret); Map<String, Object> map = (Map<String, Object>) ret; System.out.println(map.get("total")); } // 通過反射獲取參入的參數 public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); String description = ""; Method[] methods = targetClass.getMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); if (clazzs.length == arguments.length) { description = method.getAnnotation(SystemControllerLog.class).description(); break; } } } return description; } }
定義注解:
package com.zktx.platform.log2; /** * 自定義注解,攔截Controller */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.PARAMETER }) @Documented public @interface SystemControllerLog { String description() default ""; }
使用方式:
// 條件查詢 @SystemControllerLog(description = "查詢導入表") @RequestMapping("/query") public @ResponseBody Map<String, Object> findByPagination(ImportTablesPo tablesPo) { log.info("導入表查詢————————"); try { int count = tableService.findCountByParms(tablesPo); List<ImportTablesWithBLOBs> list = tableService.findByPagination(tablesPo); Map<String, Object> map = new HashMap<String, Object>(); map.put("total", count); map.put("rows", list); return map; } catch (Exception e) { e.printStackTrace(); return null; } }