1 AOP简介及作用
1.1简介
- AOP(Aspect Oriented Programing)面向切面编程,其基于Spring IOC。AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如Spring的事务,通过事务的注解配置,Spring会自动在业务方法中开启、提交业务,并且在业务处理失败时,执行相应的回滚策略等
1.2主要作用
- 提高代码的可重用性
- 业务代码编码更简洁
- 业务代码维护更高效
- 业务功能扩展更便捷
2 相关概念
- Joinpoint(连接点):就是方法
- Pointcut(切入点):就是挖掉共性功能的方法
- Advice(通知):就是共性功能,最终以一个方法的形式呈现
- Aspect(切面):就是共性功能与挖的位置的对应关系
- Target(目标对象):就是挖掉功能的方法对应的类产生的对象,这种对象是无法直接完成最终工作的
- Weaving(织入):就是将挖掉的功能回填的动态过程
- Proxy(代理):目标对象无法直接完成工作,需要对其进行功能回填,通过创建原始对象的代理对象实现
- Introduction(引入/引介) :就是对原始对象无中生有的添加成员变量或成员方法
3 AOP开发过程
- 开发阶段(开发者完成)
○ 正常开发
○ 定期切面类及定义切入点
○ 在切面类中选择合适的切入类型(下文介绍)
4注解开发案入门案例
新建maven-springboot工程,并添加AOP所需依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
</dependencies>
4.1 目标对象
@Component
public class MyDemo {
public void method1(){
System.out.println("i`m method1");
}
}
4.2 切面类
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.song.*.*(..))") //表达式介绍请看后文
// 切点固定无参无返回值,重点是声明需要增强的目标
public void pointCut() {
}
@Before(value = "pointCut() ")//@Before前置通知,在目标方法执行之前运行
public void before() {
System.out.println("before执行了");
}
@After(value = "pointCut()")//@After前置通知,在目标方法执行之前运行
public void after() {
System.out.println("after执行了");
}
}
4.3 测试类
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class AopTest {
@Autowired
private MyDemo myDemo;
@Test
public void test9() {
myDemo.method1();
}
}
4.4 代码结构
4.5 运行结果
5 execution表达式详解
标识符 | 含义 |
execution() | 表达式的主体 |
第一个“ * ”符号 | 表示返回值的类型任意 |
com.song | AOP所切的服务的包名,即,需要进行横切的业务类 |
包名后面的“…” | 表示当前包及子包 |
第二个“*” | 表示类名,*即所有类 |
.*(…) | 表示任何方法名,括号表示参数,两个点表示任何参数类型 |
例: 案例中表达式:execution(* com.song. * .*(. .)),表示的含义如下:
对com.song目录机器目录下的子类中的任意形参类型的所有方法进行增强.
6 切入类型(通知类型)
通知类型 | 对应注解 |
前置通知:在目标方法执行之前运行 | @Before |
后置通知:在方法正常执行完成进行通知(可获取返回值) | @Around |
抛出异常后通知:可以访问到异常对象,且可以指定在出现特定异常时在执行通知 | @AfterThrowing |
后置通知:设置返回后通知(可获取返回值) | @AfterReturning |
方法执行后通知: 在目标方法执行后无论是否发生异常,执行通知,不能访问目标方法的执行的结果 | @After |