1.Mavenjava
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2.java代碼web
package cn.no7player.aspect; 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; /** * 自定義註解 攔截service 方法名稱描述 * @date 2016年10月13日 */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SystemServiceLog { String description() default ""; }
3.切面WebLogAspectspring
package cn.no7player.aspect; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @Aspect @Component public class WebLogAspect { private Logger logger = Logger.getLogger(getClass()); //第一個*表示全部的返回類型 //包名:表示須要攔截的包名,後面的兩個句點表示當前包和當前包的全部子包 //第二個*號:表示類名,*號表示全部的類 //*(..):最後這個星號表示方法名,*號表示全部的方法,後面括弧裏面表示方法的參數,兩個句點表示任何參數 @Pointcut("execution(* cn.no7player.controller..*.*(..))") public void webLog() {} /** * * 說明: Before 在覈心業務執行前執行,不能阻止核心業務的調用。 * @param joinPoint * @throws Throwable * @author 胥攀 * @time:2016年10月13日 下午2:50:30 */ @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 接收到請求,記錄請求內容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 記錄下請求內容 logger.info("URL : " + request.getRequestURL().toString()); logger.info("HTTP_METHOD : " + request.getMethod()); logger.info("IP : " + request.getRemoteAddr()); logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs())); } /** * * 說明:After 核心業務邏輯退出後(包括正常執行結束和異常退出),執行此Advice * @param ret * @throws Throwable * @author 胥攀 * @time:2016年10月13日 下午2:51:09 */ @AfterReturning(returning = "ret", pointcut = "webLog()") public void doAfterReturning(Object ret) throws Throwable { // 處理完請求,返回內容 logger.info("RESPONSE : " + ret); } /** * * 說明:異常處理 * @param joinPoint * @param e * @throws ClassNotFoundException * @author 胥攀 * @time:2016年10月13日 下午3:27:52 */ @AfterThrowing(value = "webLog()", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Throwable e) throws ClassNotFoundException { String des = getServiceMthodDescription(joinPoint); Logger log = Logger.getLogger(joinPoint.getTarget().getClass()); log.error("-------------------afterThrowing.handler.start-------------------"); if(!des.equals("")){ log.error("方法描述:" + des); } log.error(getMethodNameAndArgs(joinPoint)); log.error("ConstantUtil.getTrace(e): " + getTrace(e)); log.error("異常名稱:" + e.getClass().toString()); log.error("e.getMessage():" + e.getMessage()); log.error("-------------------afterThrowing.handler.end-------------------"); } /** * 將異常信息輸出到log文件 * @param t * @return */ public static String getTrace(Throwable t) { StringWriter stringWriter= new StringWriter(); PrintWriter writer= new PrintWriter(stringWriter); t.printStackTrace(writer); StringBuffer buffer= stringWriter.getBuffer(); return buffer.toString(); } /** * 獲取方法名和參數 * @param joinPoint * @return */ private String getMethodNameAndArgs(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); StringBuffer sb = new StringBuffer("請求方法:"); sb.append(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "("); for (int i = 0; i < args.length; i++) { sb.append("arg[" + i + "]: " + args[i] + ","); } if (args.length > 0) { sb.deleteCharAt(sb.length() - 1); } sb.append(")"); return sb.toString(); } /** * 獲取註解中對方法的描述信息 用於service層註解 * @param joinPoint * @return * @throws ClassNotFoundException */ public static String getServiceMthodDescription(JoinPoint joinPoint) throws ClassNotFoundException { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); String description = ""; for (Method method : methods) { if (method.getName().equals(methodName) && method.isAnnotationPresent(SystemServiceLog.class)) { SystemServiceLog serviceLog = method.getAnnotation(SystemServiceLog.class); description =serviceLog.description(); break; } } return description; } }
日誌信息apache
[ INFO ] [2016-10-13 15:29:15] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] [180] - Initializing Spring FrameworkServlet 'dispatcherServlet' [ INFO ] [2016-10-13 15:29:15] org.springframework.web.servlet.DispatcherServlet [487] - FrameworkServlet 'dispatcherServlet': initialization started [ INFO ] [2016-10-13 15:29:15] org.springframework.web.servlet.DispatcherServlet [506] - FrameworkServlet 'dispatcherServlet': initialization completed in 13 ms [ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [50] - URL : http://localhost:7010/hello [ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [51] - HTTP_METHOD : GET [ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [52] - IP : 0:0:0:0:0:0:0:1 [ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [53] - CLASS_METHOD : cn.no7player.controller.HelloController.hello [ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [54] - ARGS : [123] [ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [84] - -------------------afterThrowing.handler.start------------------- [ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [86] - 方法描述:hello 方法 [ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [88] - 請求方法:cn.no7player.controller.HelloController.hello(arg[0]: 123) [ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [89] - ConstantUtil.getTrace(e): java.lang.ArithmeticException: / by zero at cn.no7player.controller.HelloController.hello(HelloController.java:18) at cn.no7player.controller.HelloController$$FastClassBySpringCGLIB$$8fb34a96.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)