springboot(十二)AOP的使用
概述:
说起AOP就不得不说下OOP了,OOP中引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。但是,如果我们需要为部分对象引入公共部分的时候,OOP就会引入大量重复的代码。例如:日志功能。
springboot集成AOP:
新建项目:springboot-aop,pom.xml
<dependencies> <!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
新建web层测试接口:TestController.java
@RestController
public class TestController {
private final static Logger logger=LoggerFactory.getLogger(TestController.class);
@GetMapping("/test")
public String test(String name){
logger.info("进入controller test方法");
return "name:"+name;
}
}
新建切面类:TestAspect.java,实现web层的日志切面
@Aspect
@Component
public class TestAspect {
private final static Logger logger= LoggerFactory.getLogger(TestAspect.class);
/**
* 指定切点
*/
@Pointcut("execution(public * com.example.springbootaop.controller.TestController.*(..))")
public void webLog(){}
/**
* 前置通知:方法调用前被调用
* @param joinPoint
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint){
logger.info("doBefore 方法执行之前");
Signature signature = joinPoint.getSignature();
//获取request
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
logger.info("url={}",request.getRequestURI());
//method
logger.info("method={}",request.getMethod());
//ip
logger.info("ip={}",request.getRemoteAddr());
//代理类
logger.info("代理类:"+signature.getDeclaringTypeName());
//代理类法
logger.info("代理类方法:"+signature.getName());
//请求参数名称
MethodSignature methodSignature = (MethodSignature) signature;
String[] parameterNames = methodSignature.getParameterNames();
logger.info("parameterNames={}", Arrays.toString(parameterNames));
//请求参数值
logger.info("parameterValues={}", Arrays.toString(joinPoint.getArgs()));
}
/**
* 后置通知:方法调用后被调用
*/
@After("webLog()")
public void doAfter(){
logger.info("doAfter:方法执行之后");
}
/**
* 获取返回值
* @param object
*/
@AfterReturning(returning = "object",pointcut = "webLog()")
public void doAfterReturning(Object object){
logger.info("response={}",object);
}
}
注:@Component 注解把类给ioc容器管理
@Aspect 注解 标明为切面类
@Pointcu t注解 定义的切入点
@Before 注解 切入点的前置通知
@After 注解 切入点的后置通知
@AfterReturning 注解 记录请求返回的对象。
测试:
启动项目,访问 localhost:8080/test?name=zhangsan
执行顺序:访问test接口---> 前置通知(doBefore) ---> 切入点方法(controller test方法) --> 后置通知(doAfter) --> 请求返回的对象(doAfterReturning)
