AOP是一种编码规范,是一种思想,是面向切面编程的一种思想。
是指将通用逻辑从业务逻辑中分离出来统一处理,
image.png
如图中所讲 记录请求和记录回复两个模块就可以分离出来,统一处理,中间的部分就是各自的业务处理部分。
添加AOP第一步:
添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步:
建立处理文件,建立Aspect文件夹,建立HttpAspect类
package com.imooc.aspect;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/*
统一处理请求类
*/
//使用AOP技术需要使用@Aspect注解
//@Component 把类注入到spring容器中(泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。)
@Aspect
@Component
public class HttpAspect {
//使用Before注解,在执行log方法前先执行“execution(public * com.imooc.controller.GirlController.getgirlslist(..))”
//执行com.imooc.controller.GirlController.getgirlslist(..)的getgirlslist()方法
//getgirlslist(..) 括号中的..是指这个方法中不管什么参数都会拦截,其实什么都不加也可以
//com.imooc.controller.GirlController.*(..) 把方法名换成* 星号是指该类中所有的方法都会被拦截
// @Before("execution(public * com.imooc.controller.GirlController.getgirlslist(..))")
@Before("execution(public * com.imooc.controller.GirlController.*(..))")
public void log(){
System.out.println("执行方法前,使用Aop统一处理日志");
}
//在方法执行完后打印日志
@After("execution(public * com.imooc.controller.GirlController.*(..))")
public void doAfter(){
System.out.println("执行方法后,使用Aop统一处理日志");
}
}
使用@Pointcut注解简化代码:
@Pointcut 注解,切入点注解,从哪个类开始切入使用AOP统一处理技术,
@Before和@After注解中都写入("log()")示例代码如下:
//为了使代码更简单,可以这样写,使用@Pointcut注解
// @Before("execution(public * com.imooc.controller.GirlController.*(..))")
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
public void log(){
}
//@Before注解可以这样写,调用方法之前先调用log()方法
@Before("log()")
public void doBefore(){
System.out.println("执行方法前,使用Aop统一处理日志");
}
//在方法执行完后打印日志
// @After("execution(public * com.imooc.controller.GirlController.*(..))")
@After("log()")
public void doAfter(){
System.out.println("执行方法后,使用Aop统一处理日志");
}
使用Logger打印日志,统一日志打印风格,代码如下:
//定义一个私有的常量,用来存储日志
private final static Logger logger= LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
public void log(){
}
//@Before注解可以这样写,调用方法之前先调用log()方法
@Before("log()")
public void doBefore(JoinPoint joinPoint){
logger.info("执行方法前,使用Aop统一处理日志");
//获取url、method、ip、类、方法等信息并打印成日志
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());
//获取方法,需要用joinpoint方法,先获取类名,再获取方法名
logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"."+
joinPoint.getSignature().getName());
//使用joinpoint方法获取参数名
logger.info("args={}",joinPoint.getArgs());
}
//在方法执行完后打印日志
@After("log()")
public void doAfter(){
logger.info("执行方法后,使用Aop统一处理日志");
}
在postman中调接口,查看控制台日志结果:
image.png
如何获取返回的内容呢?
需要先在Girl类中重写toString方法,要不然返回类的对象为哈希码
//重写toString()方法
@Override
public String toString() {
return "Girl{" +
"id=" + id +
", cupSize='" + cupSize + '\'' +
", age=" + age +
'}';
}
在httpAspct类中写:
//获取接口返回的内容
@AfterReturning(returning = "object",pointcut = "log()")
public void doAfterReturining(Object object){
logger.info("returning={}",object);
}
在postman中调接口,查看控制台日志结果:
image.png
网友评论