标签:
一、背景:
1.由于公司最近在拆分之前的项目,打算把项目改为前后端分离的模式,所以我们后端这边都在做接口的开发
2.最近也在和其他的公司对接他们的接口,在对接的过程中发现他们的接口调用都是有日志存储的,所以突发奇想就想用spring的aop做这个东西玩玩(其实好像拦截器也能实现)。
二、过程记录
1.在spring的配置文件中增加xsd文件
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
2.修改配置文件,增加:
3.编写aspect类
package com.dreyer.ssm.aspect;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* @Description 对api调用的监控
* @author Dreyer
* @date 2015年10月25日 下午9:04:45
* @version 1.0
*/
@Component
public class ApiMonitorAspect {
private Logger logger = Logger.getLogger(ApiMonitorAspect.class);
@Around(value = "execution(public * com.dreyer.ssm.controller..*.*(..))")
public Object monitor(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 请求的服务器
String serverName = request.getServerName();
// 请求的端口
int serverPort = request.getServerPort();
// Context路径
String contextPath = request.getContextPath();
// Servlet的路径
String servletPath = request.getServletPath();
logger.info("请求路径:" + request.getScheme() + ":" + serverName + ":" + serverPort + contextPath + servletPath);
Enumeration parameters = request.getParameterNames();
String element = "";
while (parameters.hasMoreElements()) {
element = parameters.nextElement();
logger.info("param key:" + element + " == " + request.getParameter(element));
}
long start = System.currentTimeMillis();
try {
return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
} catch (Throwable e) {
throw e;
} finally {
logger.info("此次请求耗时:" + (System.currentTimeMillis() - start) +" ms");
}
}
}
4.测试
对controller中的任何一个方法进行调用方法,会输出日志(最后一行忽略)
[com.dreyer.ssm.aspect.ApiMonitorAspect]请求路径:http:localhost:8080/SSM/user/login.do
[com.dreyer.ssm.aspect.ApiMonitorAspect]param key:phone == 13122222222
[com.dreyer.ssm.aspect.ApiMonitorAspect]param key:password == 123456
[com.dreyer.ssm.aspect.ApiMonitorAspect]此次请求耗时:6 ms
[com.dreyer.ssm.exception.handler.GlobalExceptionHandler]系统发生错误,错误代码:1002,错误信息:用户不存在
spring aop的应用可分为两种,一种是基于aspectJ,需要在配置文件中配置 ,切入点表达式写在类中,aspect类的初始化需要交给spring管理。
一种是基于Schema的AOP支持,需要通过将aspect类的信息写在配置文件中
...
...
至于两者的优劣,可参考文档:http://shouce.jb51.net/spring/
标签:
原文地址:http://my.oschina.net/u/2375667/blog/521937