首先,AOP是一种编程思想,与之对应的还有OOP(面向对象),POP(面向过程);
AOP的作用:将用面向对象构建的庞大的体系“横切”,并将那些影响了多个类的“公共行为”进行了封装,封装成一个可以重用的模块;——这个模块就是切面。
AOP核心思想:将“通用逻辑”从 业务逻辑 中抽离。
AOP 的使用:
1,添加依赖——spring-boot-starter-aop
2,建立处理文件 TestAspect,并在此类上添加@Aspect @Component注解
3,在此类中书写逻辑代码:
@Before的使用——在方法执行“之前”,执行特定方法,代码如下:
@Before("excution(public * com.test.controller.TestController.test(..))") // 参数中两点..表示任意参数
public void logBeforeOne(){
System.out.println("在test方法执行前执行此方法");
}
@Before("excution(public * com.test.controller.TestController.*(..))") // 参数中两点..表示任意参数
public void logBeforeAll(){
System.out.println("此controller层的所有方法执行前执行此方法");
}
@After的使用——在方法执行“之后”,执行特定方法,代码如下:
@After("excution(public * com.test.controller.TestController.test(..))") // 参数中两点..表示任意参数
public void logAfterOne(){
System.out.println("在test方法执行后执行此方法");
}
改进1!—— 因为上述代码中excution(......)代码重复,我们可以抽取为一个公共方法;
改进2!——System.out.println()我们可以使用spring自带的slf4j来打印,这样可以看到什么时候,哪个类哪个方法打印的东西;
@PointCut 使用
private final staitc Logger logger = LoggerFactory.getLogger(TestAspect.class);//使用slf4j初始化log对象
@PointCut("excution(public * com.test.controller.TestController.*(..))") // 面向切面
public void log(){
}
//使用@PointCut注解的公共类
@Before("log()") //
public void logBeforeAll(){
logger.info("此controller层的所有方法执行前执行此方法");
}
@After("log()") //
public void logAfterAll(){
logger.info("此controller层的所有方法执行后执行此方法");
}
- 拦截url, ip, 请求方法,类方法,参数
@Before("log()") //
public void logBeforeAll(JoinPoint joinPoint){//JoinPoint可提取类中的东西
ServletRequestAttributes attributes = (ServletRequestAttributes )RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();//这里选javax包下的request
//url
logger.info("url={}",request.getRequestUrl());
//method
logger.info("method={}",request.getMethod());
//ip
logger.info("ip={}",request.getRemoteAddr(0);
//类名 + 类方法
logger.info("classMethod=
{}",joinPoint.getSignature().getDeclareingTypeName()+"."+joinPoint.getSignature().getName();
//参数
logger.info("args={}",joinPoint.getArgs());
}
- 获取controller层方法执行完毕后,返回的内容:
@AfterReturning(returning = "object",pointCut="log()")
public void doAfterReturning(Object object){
logger.info("response={}",object.toString());//需要返回的对象重写了toString()方法才能打印值,否则为地址值
}