之 横切关注点、通知、切点、连接点、引入、织入、创建切点

  1. 知识背景
    1. 软件系统可以看成是由一组关注点组成的,其中,直接的业务关注点,是直切关注点。而为直切关注点提供服务的,就是横切关注点。

  2. 面向切面的基本原理
    1. 什么是面向切面编程
      1. 横切关注点:影响应用多处的功能(安全、事务、日志)
      2. 切面:横切关注点被模块化为特殊的类,这些类称为切面
        1. 优点:
          每个关注点现在都集中于一处,而不是分散到多处代码中
          服务模块更简洁,服务模块只需关注核心代码。
    2. AOP 术语

      1. 通知:
        1. 定义:切面也需要完成工作。在 AOP 术语中,切面的工作被称为通知。
        2. 工作内容:通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决何时执行这个工作。
        3. Spring 切面可应用的 5 种通知类型:
          Before——在方法调用之前调用通知
          After——在方法完成之后调用通知,无论方法执行成功与否
          After-returning——在方法执行成功之后调用通知
          After-throwing——在方法抛出异常后进行通知
          Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
      2. 连接点:
        1. 定义:连接点是一个应用执行过程中能够插入一个切面的点。
        2. 连接点可以是调用方法时、抛出异常时、甚至修改字段时、
        3. 切面代码可以利用这些点插入到应用的正规流程中
        4. 程序执行过程中能够应用通知的所有点。
      3. 切点:
        1. 定义:如果通知定义了“什么”和“何时”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。
        2. 通常使用明确的类或者方法来指定这些切点。
        3. 作用:定义通知被应用的位置(在哪些连接点)
      4. 切面:
        1. 定义:切面是通知和切点的集合,通知和切点共同定义了切面的全部功能——它是什么,在何时何处完成其功能。
      5. 引入:
        1. 引入允许我们向现有的类中添加方法或属性
      6. 织入:
        织入是将切面应用到目标对象来创建的代理对象过程。
        切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有多个点可以织入
        1. 编译期——切面在目标类编译时期被织入,这种方式需要特殊编译器。AspectJ的织入编译器就是以这种方式织入切面。
        2. 类加载期——切面在类加载到 JVM ,这种方式需要特殊的类加载器,他可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5 的 LTW 就支持这种织入方式
        3. 运行期——切面在应用运行期间的某个时刻被织入。一般情况下,在织入切面时候,AOP 容器会为目标对象动态的创建代理对象。Spring AOP 就是以这种方式织入切面。

  3. Spring 对 AOP 的支持
    1. 并不是所有的 AOP 框架都是一样的,他们在连接点模型上可能有强弱之分。
          有些允许对字段修饰符级别应用通知
          有些支持方法调用连接点
    2. Spring 提供的 4 种各具特色的 AOP 支持
      1. 基于代理的经典 AOP;
      2. @AspectJ 注解驱动的切面;
      3. 纯 POJO 切面;
      4. 注入式 AspectJ 切面;
    3. Spring 在运行期间通知对象
      1. 通过在代理类中织入包裹切面,Spring 在运行期间将切面织入到 Spring 管理的 Bean 中。

        代理类封装了目标类,并拦截被通知的方法调用,再将调用转发给真正的目标 Bean.
        当拦截到方法调用时,在调用目标 Bean 方法之前,代理会执行切面逻辑。
        当真正应用需要被代理的 Bean 时,Spring 才创建代理对象。如果使用 ApplicationContext,在 ApplicationContext 从 BeanFactory 中加载所有 Bean 时,Spring 创建代理对象,因为 Spring 在运行时候创建代理对象,所以我们不需要特殊的编译器来织入 Spring AOP 的切面。
    4. Spring 支持方法创建连接点
      1. 因为 Spring 基于动态代理,所以 Spring 只支持方法连接点。
      2. Spring 缺失对字段连接点的支持,无法让我们更加细粒度的通知,例如拦截对象字段的修改
      3. Spring 缺失对构造器连接点支持,我发在 Bean 创建时候进行通知。

  4. 使用切点选择连接点
    1. 切点用于准确定位,确定在什么地方应用切面通知。
    2. Spring 定义切点
      1. 在 Spring AOP 中,需要使用 AspectJ 的切点表达式来定义切点。
        AspectJ 指示器
        描述
        arg ()
        限制连接点的指定参数为指定类型的执行方法
        @args ()
        限制连接点匹配参数由指定注解标注的执行方法
        execution ()
        用于匹配连接点的执行方法
        this ()
        限制连接点匹配 AOP 代理的 Bean 引用为指定类型的类
        target ()
        限制连接点匹配特定的执行对象,这些对象对应的类要具备指定类型注解
        within()
        限制连接点匹配指定类型
        @within()
        限制连接点匹配指定注释所标注的类型(当使用 Spring AOP 时,方法定义在由指定的注解所标注的类里)
        限制匹配带有指定注释的连接点
                                         Spring 借助 AspectJ 的切点表达式语言来定义 Spring 切面
      2. 创建自己的切点

        1. execution( ) 指示器选择 Instrument 的 play( ) 方法。
          方法表达式是以 * 号开头,标识了我们不关心的方法返回值的类型。
          * 后我们指定了权限定类名和方法名。
          对于方法的参数列表,使用(..)标识切点选择任意的 play( ) 方法,无论入参是什么。
        2. 假设我们需要匹配切点仅匹配 com.Springinaction.springidol 包。可以使用 within()

          注意 && 是将 execution( ) 和 within( ) 连接起来,形成的 and 关系。同理也可以使用 || 或关系、!非关系
      3. 创建 Spring 的 bean( ) 指示器
        1. Spring 2.5 引入一个新的 bean( ) 指示器,该指示器允许我们在切点表达式中使用 Bean ID 来标识 Bean
          bean( ) 使用 Bean ID 或 Bean 名称作为参数来限制切点只匹配特定 Bean。
        2. 如下,我们希望执行 Instrument 的 play( ) 方法时候应用通知,但限定 Bean 的 ID 为 eddie

          还可以使用非操作作为除了指定 ID 的 Bean 以外的其他 Bean应用通知

          在此场景下,切面会通知被编织到所有 ID 不为 eddie 的 Bean 中

  5. 在 XML 中声明切面
    1. Spring 的 AOP 配置元素简化了基于 POJO 切面声明
      AOP 配置元素
      描述
      <aop : advisor> 定义 AOP 通知器
      <aop : after>
      定义 AOP 后置通知(不管被通知方法是否执行成功)
      <aop : after-returing>
      定义 AOP after-returing 通知
      <aop : after-throwing>
      定义 AOP after-throwing 通知
      <aop : around> 定义 AOP 环绕通知
      <aop : aspect> 定义切面
      <aop : aspectj-autoproxy>
      启动 @AspectJ 注解驱动的切面
      <aop : before>
      定义 AOP 前置通知
      <aop : config> 顶层的 AOP 配置元素,大多数 <aop : *> 元素必须包含在 <aop : config>元素内
      <aop : declare-parents>
      为被通知的对象引入额外接口,并透明的实现
      <aop : pointcut>
      定义切点

转载于:https://my.oschina.net/u/2378713/blog/670056

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值