springboot-web进阶(二)——AOP统一处理请求
一、AOP使用示例
AOP的概述在spring篇已经存在,这里不再赘述
1.准备
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2.编写Aspect类
这里需要特别注意类上面的两个注解,别忘记@Componet!
package com.example.demo.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* aspect切面类
* 添加@Aspect注解标注为切面类
* 添加@Componet让spring进行实例化
* @author zcc ON 2018/2/9
**/
@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
@Before("execution(public * com.example.demo.controller.GirlController.getList(..))")
public void log() {
log.info("调用了一次getList()!");
}
}
3.验证
发送请求:
查看日志:
并且也容易看出,这是在它之前执行的,也就验证了这是Before注解!
二、AOP表达式与AOP特性介绍
1.语法
execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选))
2.示例
参考:http://blog.csdn.net/qq525099302/article/details/53996344
3.使用PointCut提取公共execution表达式
@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("execution(public * com.example.demo.controller.GirlController.*(..))")
public void log() {
}
@Before("log()")
public void logBefore() {
log.info("开始调用前!");
}
@After("log()")
public void logAfter() {
log.info("调用完成后!");
}
}
4.使用JoinPoint得到被增强方法的信息
@Before("execution(* com.abc.service.*.many*(..))")
public void permissionCheck(JoinPoint point) {
System.out.println("@Before:模拟权限检查...");
System.out.println("@Before:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@Before:被织入的目标对象为:" + point.getTarget());
}
完整参考:https://my.oschina.net/itblog/blog/211693
三、AOP日志请求统一处理
1.Aspect类
package com.example.demo.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* aspect切面类
* 添加@Aspect注解标注为切面类
* 添加@Componet让spring进行实例化
* @author zcc ON 2018/2/9
**/
@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("execution(public * com.example.demo.controller.GirlController.*(..))")
public void log() {
}
@Before("log()")
public void logBefore(JoinPoint joinPoint) {
// 得到request对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// URL
log.info("url is:{}", request.getRequestURL());
// method
log.info("method is:{}", request.getMethod());
// ip地址
log.info("ip is:{}", request.getRemoteAddr());
// 类方法
log.info("class method is:{}", joinPoint.getSignature().getName());
// 参数
log.info("param is:{}", joinPoint.getArgs());
}
@After("log()")
public void logAfter() {
log.info("调用完成后!");
}
}
2.结果
日志:
3.@AfterReturning的用法
@AfterReturning(returning = "obj", pointcut = "log()")
public void afterReturn(Object obj) {
log.info("return obj:{}", obj.toString());
}
// 需要注意它的两个参数,一个是切点,一个是返回的对象