前言
日志是所有系統必不可少的部分,而AOP在MVC通常用於監控方法調用,可以生成一個traceid,記錄從用戶調用到底層數據庫的數據鏈路,幫助監控和排查問題。
AOP
現在做一個簡單的前置切面,用來記錄方法和入參,需要修改如下文件

public class ControllerAspect { private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ControllerAspect.class); public void before(JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); System.out.println("方法名:"+methodSignature.getMethod().getName()+" 參數列表:"+ArrayToParameterString(methodSignature.getParameterNames(),joinPoint.getArgs())); } private String ArrayToParameterString(String[] parameterNames,Object[] parameterValues) { StringBuffer sb = new StringBuffer(); if (parameterNames != null && parameterNames.length > 0) { for (int i = 0; i < parameterNames.length; i++) { sb.append(parameterNames[i]); sb.append(":"); sb.append(parameterValues[i]); sb.append(";"); } } return sb.toString(); } }
兩個pom.xml需要加入依賴,如
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.5.RELEASE</version> </dependency>
applicationContext.xml需要加入以下配置
<bean id="controllerAspect" class="cn.com.test.springmvc.common.aop.ControllerAspect"> </bean> <aop:config> <aop:aspect ref="controllerAspect"> <aop:pointcut id="controlPointcut" expression="execution(* cn.com.test.springmvc.web.*.*(..))"></aop:pointcut> <aop:before method="before" pointcut-ref="controlPointcut"></aop:before> </aop:aspect> </aop:config>
dispatcher-servlet.xml需要加入以下配置
<aop:aspectj-autoproxy proxy-target-class="true"/>
運行后可以看到控制台有輸出,如下
方法名:getDeptList 參數列表:name:null;
日志
日志框架加入和使用也比較簡單,需要修改如下文件

public class ControllerAspect { private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ControllerAspect.class); public void before(JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); logger.info("方法名:"+methodSignature.getMethod().getName()+" 參數列表:"+ArrayToParameterString(methodSignature.getParameterNames(),joinPoint.getArgs())); } private String ArrayToParameterString(String[] parameterNames,Object[] parameterValues) { StringBuffer sb = new StringBuffer(); if (parameterNames != null && parameterNames.length > 0) { for (int i = 0; i < parameterNames.length; i++) { sb.append(parameterNames[i]); sb.append(":"); sb.append(parameterValues[i]); sb.append(";"); } } return sb.toString(); } }
需要加入依賴,如
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.8.0-alpha2</version> </dependency>
還有日志配置,配置日志級別,輸出目錄等
log4j.rootLogger=INFO,FILE,stdout #file log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender log4j.appender.FILE.DatePattern='.'yyyy-MM-dd log4j.appender.FILE.File=./logs/out.log log4j.appender.FILE.Append=true log4j.appender.FILE.Threshold=DEBUG log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ] %p:%m%n log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern= [%d{yyyy-MM-dd HH:mm:ss a}]:%p %l%m%n
運行后,可以在控制台看到日志輸出和在Tomcat的目錄bin下面看到日志文件。
攔截器
攔截器其實也是aop思想中的一種實現,可以看成是特定於controller層的aop,根據對request和Reponse做更細化的處理,加入攔截器需要修改以下文件

public class ControllerInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("鏈接是"+request.getRequestURL().toString()); return true; } }
pom.xml加入依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency>
dispatcher-servlet.xml需要加入以下配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.com.test.springmvc.common.interceptor.ControllerInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
運行后可以看到
鏈接是http://localhost:8080/dept/getList
小結
本文只是簡單演示了aop和日志和攔截器的功能,這只是冰山一角,AOP的功能不止這樣的。