一、XML方式
1、pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.2.9.RELEASE</version>
</dependency>
// 或
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
// 或
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>
2、自定义注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BusiLog {
String busCode();
String desc() default "";
}
3、定义aop类
public class BusiLogAspect {
//@Autowired
//HttpServletRequest request;
public void doBefore(JoinPoint pjp) {
String sessionId = null;
try {
MethodSignature signature = (MethodSignature)pjp.getSignature();
BusiLog annotation = signature.getMethod().getAnnotation(BusiLog.class);
if (null == annotation) {
return;
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null == attributes || null == attributes.getRequest()) {
return;
}
// 获取会话ID
HttpServletRequest request = attributes.getRequest();
sessionId= request.getHeader("sessionId");
// 获取请求入参
JSONObject req = null;
Object[] args = pjp.getArgs();
if (args != null) {
for(Object arg : args){
if (arg instanceof String) {
String reqStr = (String)arg;
if (StringUtils.isNotBlank(reqStr)) {
req = JSON.parseObject(reqStr);
}
}
/*else if (arg instanceof HttpServletRequest) {
request = (HttpServletRequest)arg;
sessionId = request.getHeader("sessionId");
}*/
}
}
// 打印日志
if (null != req) {
printLog(sessionId, annotation.busCode(), req);
/*****省略*****/
}
} catch (Exception e) {
logger.error(sessionId, e);
}
}
}
三种获取Request的方法。
4、applicationContext.xml配置
<bean id="busiLogAspect" class="cn.aspect.BusiLogAspect"/>
<aop:config>
<aop:pointcut expression="@annotation(cn.annotion.BusiLog)" id="busiLogPointCut" />
<aop:aspect id="logAspect" ref="busiLogAspect">
<aop:before method="doBefore" pointcut-ref="busiLogPointCut" />
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy/>
<!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->
<!-- <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="false"/> -->
aop:aspectj-autoproxy:声明自动为Spring容器中配置@aspectj切面的bean创建代理。
proxy-target-class="true":默认false:JDK代理,true:强制使用CGLIB代理。默认情况下,目标类是接口或实现了接口,就会使用JDK动态代理(基于接口),否则spring将自动使用CGLIB代理(基于继承)。
expose-proxy:用来解决对象内部this调用无法被切面增强的问题。(this.y() --> 1、((A)AopContext.currentProxy()).y(),2、expose-proxy=true)。
5、web.xml
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
如果web.xml不配置这个监听,RequestContextHolder.getRequestAttributes()就取不到request信息。
6、使用
@RestController
public class TestController {
@BusiLog
@RequestMapping("/hello")
public String hello(HttpServletRequest request, @RequestBody String param){
return "hello " + param;
}
}
二、注解方式
1、pom.xml
同上
2、自定义注解类
同上
3、定义aop类
@Aspect
@Component
public class BusiLogAspect {
@Pointcut("@annotation(cn.annotion.BusiLog)")
public void auditAspect(){
}
@Before("auditAspect()")
public void doBefore(JoinPoint pjp) {
/*****内容同上,省略*****/
}
}
4、web.xml
同上
5、使用
同上