目录
[1.1 什么是AOP](#1.1 什么是AOP)
[1.2 AOP体系与概念](#1.2 AOP体系与概念)
[2.1 新建一个SpringBoot项目,无需选择依赖](#2.1 新建一个SpringBoot项目,无需选择依赖)
[2.2 设置好本地Maven配置后,在pom.xml文件里添加添加maven依赖](#2.2 设置好本地Maven配置后,在pom.xml文件里添加添加maven依赖)
[2.3 创建一个业务类接口](#2.3 创建一个业务类接口)
[2.4 在实体类实现接口业务](#2.4 在实体类实现接口业务)
[2.5 在单元测试运行结果](#2.5 在单元测试运行结果)
[2.6 创建切面类](#2.6 创建切面类)
[2.7 再次运行测试](#2.7 再次运行测试)
介绍
1.1 什么是AOP
AOP(Aspect Oriented Programming),面向切面思想,是Spring的三大核心思想之一(两外两个:IOC-控制反转、DI-依赖注入)。
那么AOP为何那么重要呢?
在我们的程序中,经常存在一些系统性的需求,比如权限校验、日志记录、统计等,这些代码会散落穿插在各个业务逻辑中,例如下面这个示意图:
有多少业务操作,就要写多少重复的校验和日志记录代码,这显然是无法接受的。当然,用面向对象的思想,我们可以把这些重复的代码抽离出来,写成公共方法,就是下面这样:
这样,代码冗余和可维护性的问题得到了解决,但每个业务方法中依然要依次手动调用这些公共方法,也是略显繁琐。有没有更好的方式呢?有的,为了解决这个问题,面向切面编程(AOP)应运而生。AOP将权限校验、日志记录等非业务代码完全提取出来,与业务代码分离,并寻找节点切入业务代码中:
AOP通过预编译方式和运行动态代理实现程序功能的统一维护,AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各部分进行隔离,是开发人员在编写业务逻辑时,专注核心业务,从而降低业务逻辑各模块之间的耦合度,提高代码重用和开发效率。
AOP使用横向抽取机制,取代纵向集成体系的重复代码建设。使用Aspect,使业务逻辑只关注业务本身,将日志管理、事务处理、性能统计、异常处理、权限控制等代码从业务逻辑代码中抽离,从而实现改变这些行为的时候不影响业务逻辑代码。
1.2 AOP体系与概念
Spring AOP和AspectJ
目前流行的AOP框架分别为Spring AOP和AspectJ。
AOP相关术语
简单地去理解,其实AOP要做三类事:
-
在哪里切入,也就是权限校验等非业务操作在哪些业务代码中执行。
-
在什么时候切入,是业务代码执行前还是执行后。
-
切入后做什么事,比如做权限校验、日志记录等。
因此,AOP的体系可以梳理为下图:
AOP简单实现
下面我们通过一个简单的案例来演示一下AOP的初级应用:
2.1 新建一个SpringBoot项目,无需选择依赖
2.2 设置好本地Maven配置后,在pom.xml文件里添加添加maven依赖
java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.3 创建一个业务类接口
如图,建立对应的软件包和接口,并在接口创建方法:
2.4 在实体类实现接口业务
注意,一定要添加Service注解
2.5 在单元测试运行结果
2.6 创建切面类
java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.StringJoiner;
@Component
@Aspect
public class LogAspect {
@Before("execution(* com.example.aopdemo.service..*.*(..))")
public void sysLog(JoinPoint jp){
StringJoiner log = new StringJoiner("|","{","}");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss");
log.add(formatter.format(LocalDateTime.now()));
//当前执行的业务方法名称
String methodName = jp.getSignature().getName();
log.add(methodName);
//方法的参数
Object[] args = jp.getArgs();
for(Object arg:args){
log.add(arg == null ? "-" : arg.toString() );
}
System.out.println("AOP日志启动!" + log);
}
2.7 再次运行测试
再次运行就发发现我们的日志已经添加进去了,并且没有对原代码进行改变,这就是AOP的丝滑之处。
总结
AOP使用横向抽取机制,取代纵向集成体系的重复代码建设。使用Aspect,使业务逻辑只关注业务本身,将日志管理、事务处理、性能统计、异常处理、权限控制等代码从业务逻辑代码中抽离,从而实现改变这些行为的时候不影响业务逻辑代码。实乃开发必备之神器也,本文到此就结束了,希望大家可以有所收获~