什么是AOP
AOP 为 Aspect Oriented Programming 的缩写,翻译为面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。通俗理解就是在不修改源代码的情况下,在主干功能里面添加新的功能。
AOP中的专业术语
-
Advisor:切面,也可以称为
Aspect
,由 切点(pointCut)和 建议(advice)组成。 -
Advice:单词意思是建议,不过国内程序员一般称为通知。建议切面在何时执行以及如何执行增强处理。说的直白点就是代理逻辑。通知分为如下几种:
- Before :前置通知,在连接点前调用。如果抛出异常则不会流转到连接点。
- After :后置通知,在连接点后调用,不管连接点是否执行正常、异常都会执行的通知。
- AfterReturning:返回通知,在连接点执行正常并返回后调用,执行正常也就是说在执行过程中没有发生异常。
- AfterThrowing:异常通知,当连接点执行发生异常时调用。
- Around:环绕通知,连接点执行的前后可以执行自定义代码。
-
Join point:连接点,在
Spring AOP
中一个连接点就是一个方法。 -
PointCut:切点,一系列连接点的集合,可以通过表达式找到一系列的连接点。
-
Target object:目标对象。被一个或多个切面建议的对象,也就是被代理对象。
-
AOP proxy:代理对象。由 AOP 框架创建的对象,使用的是JDK 动态代理或 CGLIB 代理。
-
Weaving:织入,就是将代理逻辑添加到对目标类具体连接点上,并创建代理对象的过程。
Spring 框架是基于 AspectJ 实现 AOP 操作!但各位需要知道, AspectJ 并不是 Spring 的组成部分,它是一个独立的框架,Spring AOP引入了对 AspectJ 的支持,也建议使用 AspectJ 来开发 AOP。
使用 Spring 实现 AOP 方式有两种,分别如下:
- XML 配置文件实现
- 注解实现 先来看一下不使用 AOP 的代码!
加入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
复制代码
配置类
@ComponentScan(basePackages = "com.cxyxj.aopannon")
public class AppMain {
}
复制代码
类中就一个@ComponentScan
注解。
业务代码
@Controller
public class UserController {
public String queryUser(String name){
System.out.println("查询用户信息");
return name;
}
}
复制代码
测试类
public class AppTest {
public static void main(String[] args)
{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
AppMain.class);
UserController bean = context.getBean(UserController.class);
String cxyxj = bean.queryUser("cxyxj");
System.out.println("方法返回值为 = " + cxyxj);
}
}
复制代码
测试代码,运行结果如下:
查询用户信息
复制代码
过了一段时间,项目经理跟你聊天。。。
-
项目经理:我想在
queryUser
方法中加一个方法执行开始时间和方法执行结束时间吧,但是有个要求不能改动原逻辑!你有什么好注意。 -
你:稍作考虑,我们可以使用 Spring AOP 进行实现。
-
项目经理:怎么使用 AOP 呢?
-
你:我所了解到的方式有两种,分别是 XML 配置文件实现 和 注解实现。
-
项目经理:嗯,看来你胸有成竹了,那这任务就交给你了,别让我失望哦!
-
你:嗯好的,我先写个 demo 给您过目一下。
配置文件方式
加入依赖
既然要使用 Spring AOP,那先在 pom.xml
文件中引入相关依赖:
<!--aspectj 支持-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
复制代码
Spring AOP 的依赖就不需要再次加入了,spring-context
中有 Spring AOP 的依赖。
AOP配置元素
XML方式的 AOP 配置有许多的标签,在这里进行介绍一下。
元素 | 备注 |
---|---|
aop:aspectj-autoproxy | 启用 @AspectJ 注解支持,与 @EnableAspectJAutoProxy效果一致 |
aop:config | 最外层的 AOP 元素,大多数的其他AOP元素(切面、切点、通知)需要写在 aop:config 元素内。 |
aop:advisor | 定义 AOP 通知器,通知器跟切面一样,也包括通知和切点。 |
aop:aspect | 定义一个切面,aop:aspect 元素内可以定义通知类型! |
aop:pointcut | 定义切点 |
aop:before | 前置通知,在连接点执行前调用。 |
aop:after | 后置通知,在连接点执行后调用。不管目标方法是否发生异常。 |
aop:after-returning | 返回通知,在连接点执行正常并返回后调用。 |
aop:after-throwing | 异常通知,当连接点执行发生异常时调用。 |