1.Spring AOP是什么?

Aspect Oriented Programming:面向切面编程
什么时候会出现面向切面编程的需求?按照软件重构的思想,如果多个类中出现重复的代码,就应该考虑定义一个共同的抽象类,将这些共同的代码提取到抽象类中,比如Teacher,Student都有username,那么就可以把username及相关的get、set方法抽取到SysUser中,这种情况,我们称为纵向抽取。
但是如果,我们的情况是以下情况,又该怎么办? 给所有的类方法添加性能检测,事务控制,该怎么抽取? PerformanceMonitor TransactionManager AOP就是希望将这些分散在各个业务逻辑代码中的相同代码,通过横向切割的方式抽取到一个独立的模块中,让业务逻辑类依然保存最初的单纯。

Spring AOP——简单粗暴,小白教学

抽取出来简单,难点就是如何将这些独立的逻辑融合到业务逻辑中,完成跟原来一样的业务逻辑,这就是AOP解决的主要问题。

还是看不懂?接下基础案例说明

1.1 基础案例说明

为了更好说明,我们接下来,要讲解的知识点,我们以一个常见的例子来说明
我们以数据库的操作为例来说明:
  1. 获取连接对象
  2. 执行SQL(核心业务代码)
  3. 如果有异常,回滚事务,无异常则提交事务
  4. 关闭连接
上述的几个部署,“2”是核心业务代码,其他都是非核心业务代码,但是我们又必须写 而面向切面编程就是为了解决这样的问题,将这些非核心业务代码进行抽离,这样开发者只需要关注“核心业务代码”即可。 这样开发效率自然提高。

在项目开发中,SpringAOP是非常常用的技能之一,下面我画一个图来说明,spring都做了什么

Spring AOP——简单粗暴,小白教学


2. AOP术语

2.1 一图胜千言

Spring AOP——简单粗暴,小白教学

3. Spring概述

1,AOP编程可不是Spring独有的,Spring只是支持AOP编程的框架之一,这一点非常重要,切勿搞反了关系。
2,AOP分两类,一类可以对方法的参数进行拦截,一类是对方法进行拦截,SpringAOP属于后者,所以Spring的AOP是属于方法级的

4. Spring AOP实现-基于注解的方式

@Asoect创建切面类

Spring AOP——简单粗暴,小白教学

@Before: 标识一个前置增强方法,相当于BeforeAdvice的功能.
@After: final增强,不管是抛出异常或者正常退出都会执行.
@AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行.
@AfterThrowing: 异常抛出增强,相当于ThrowsAdvice.
@Around: 环绕增强,相当于MethodInterceptor.
execution:用于匹配方法执行的连接点;

eg.

  • 任意公共方法的执行:execution(public * *(..))
  • 任何一个以“set”开始的方法的执行:execution(* set*(..))
  • AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
  • 定义在service包里的任意方法的执行: execution(* com.xyz.service.*.*(..))
  • 定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.xyz.service..*.*(..))

第一个表示匹配任意的方法返回值, …(两个点)表示零个或多个,第一个…表示service包及其子包,第二个表示所有类, 第三个*表示所有方法,第二个…表示方法的任意参数个数

  • 定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:execution(*com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
  • pointcutexp包里的任意类: within(com.test.spring.aop.pointcutexp.*)
  • pointcutexp包和所有子包里的任意类:within(com.test.spring.aop.pointcutexp..*)
  • 实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类:this(com.test.spring.aop.pointcutexp.Intf)
  • 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型
  • 带有@Transactional标注的所有类的任意方法: @within(org.springframework.transaction.annotation.Transactional) @target(org.springframework.transaction.annotation.Transactional)
  • 带有@Transactional标注的任意方法:
    @annotation(org.springframework.transaction.annotation.Transactional)
    @within和@target针对类的注解,@annotation是针对方法的注解
  • 参数带有@Transactional标注的方法:@args(org.springframework.transaction.annotation.Transactional)
  • 参数为String类型(运行是决定)的方法: args(String)

    至于@Around解析请跳转:
  • https://blog.csdn.net/qq_41981107/article/details/85260765




    参考博客:

    https://my.oschina.net/itblog/blog/211693

    https://my.oschina.net/u/3434392/blog/1625493

    相关文章: