Skip to content

Latest commit

 

History

History
128 lines (99 loc) · 6.31 KB

Learning_aop-Round1_日常使用.md

File metadata and controls

128 lines (99 loc) · 6.31 KB

1.连接点(Joinpoint)

程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入通知。连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。连接点是在应用执行过程中能够插入切面的一个点。

2.切点(Pointcut)

AOP通过“切点”定位特定的连接点。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责切点所设定的查询条件,找到对应的连接点。其实确切地说,不能称之为查询连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。

3.通知(Advice)

切面的工作被称为通知。是织入到目标类连接点上的一段程序代码。 Spring切面可以应用5种类型的通知:

  • 前置通知(Before):在目标方法被调用之前调用通知功能;
  • 后置通知(After):在目标方法完成之后调用通知,此时不会关心方 法的输出是什么;
  • 返回通知(After-returning):在目标方法成功执行之后调用通知;
  • 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  • 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调 用之前和调用之后执行自定义的行为。

4.引介(Introduction)

引入允许我们向现有的类添加新方法或属性,是一种特殊的通知。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

5.切面(Aspect)

切面由切点和通知(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义。

6.织入(Weaving)

织入是把切面应用到目标对象并创建新的代理对象的过程。 AOP有三种织入的方式: a、编译期:切面在目标类编译时被织入。这种方式需要特殊的编译器。AspectJ的织入编译器就是以这种方式织入切面的。 b、类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增 强该目标类的字节码。AspectJ 5的加载时织入(load-time weaving,LTW)就支持以这种方式织入切面。 c、运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。Spring

AOP就是以这种方式织入切面的。

AOP织入的目标/对象:

这个是一个需要注意的问题,并不是任何类都会被织入增强的;

只有使用@RestController 注解和@Controller 注解标记的类才会被织入增强。

有些例子给出了接口的定义,有些例子给出Services的定义,然而那都不是AOP的菜啊!反而误导读者。

需要做哪些配置?

对不起!真的不需要配置!

有的文章指出要使用@EnableAspectJAutoProxy 注解,然而亲测真的不需要!

因为在AOP的默认配置属性中,spring.aop.auto属性默认是开启的,也就是说只要引入了AOP依赖后,默认已经增加了@EnableAspectJAutoProxy。

织入时机

从控制台输出来看,它是在 Filter init 之后,

在拦截器注册之前织入的。

实现AOP的切面主要有以下几个要素:

使用@Aspect注解将一个java类定义为切面类 使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。 根据需要在切入点不同位置的切入内容,5种类型的通知 使用@Before在切入点开始处切入内容 使用@After在切入点结尾处切入内容 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理) 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑

概念组合

从线程栈的角度来看,,JVM处理Java程序的基本单位是方法调用。

实际上,JVM执行的最基本单位的指令(即原子操作)是汇编语言性质的机器字节码。

AOP本质上是针对方法调用的编程思路

切入点 pointcut @Pointcut(execution (* com.test.*(..)))
 |
 连接点 joinpoint 
 |
 连接点 joinpoint <-----横向切入,针对每一个方法调用作为入口进行编程 Aspect 切面
 |
 连接点 joinpoint 
 |
 连接点 joinpoint <-----横向切入,针对每一个方法调用作为入口进行编程
 |
 连接点 joinpoint 
 |
 连接点 joinpoint <-----横向切入,针对每一个方法调用作为入口进行编程
 |
 连接点 joinpoint 
 |
 |
 | 时间轴 
  
切入点          Spring代理层
 |
 连接点       MethodBeforeAdvice
 |
 连接点      try{
 |             调用真正对象          -----------> 实际业务方法
 连接点       }catch(Throwable t){
 |              ThrowsAdvice
 连接点 --->  }finally{
 |            AfterReturningAdvice
 连接点       }
 |
 连接点 
 |
 连接点 
 |
 |
 | 时间轴