• AOP


    在软件开发过程中,发布于应用程序多处的功能成为横切关注点,通常这些横切关注点是与应用程序分离的。

    横切关注点被模块化为特殊的类,称为“切面”。通过声明的方式来决定切面在何处以何种方式被应用。

    这样1,每个关注点都被集中在一个地方,而不是分散在多出代码。2,服务器比较简洁,只包含核心功能的代码,次要的关注点都被移动到切面上了。

    AOP的术语

    1, 切面:实现了横切关注点(事务、安全、日志等)的类,是通知和切点的集合

    2, 通知:通知描述了切面要完成的工作,以及切面在合适执行这个工作

    Spring的切面可以应用5种Advice
      Before :在方法调用之前调用通知
      After:之后,无论是否调用成功
      After-returning:返回之后
      After-throwing:抛出异常之后
      Around :在方法调用之前和之后通知

    3, 连接点:应用程序中可以插入前面的位置,切面代码可以通过连接点插入到应用程序中

    4, 切点:明确切面要织入的连接点的位置

    5, 引入:引入允许向已知类中加入新的方法和属性

    6, 织入:切面在指定的连接点织入到目标对象,在目标对象的声明周期中,有多个点可以织入,包括:编译期、类加载期、运行期

     Spring AOP是在运行期织入的。

    Spring提供了4种类型的AOP支持:
    1,基于代理的经典Spring AOP;
    2,纯POJO切面;使用xml配置
    3,@AspectJ注解驱动的切面;使用注解配置
    4,注入式AspectJ切面(适用于Spring各版本) 。

    Spring的通知是使用java编写,定义通知所应用的切点通常会使用注解或在Spring配置文件里采用XML来编写。

    通过在代理类中包裹切面, Spring在运行期把切面织入到Spring管理的bean中

    Spring只支持方法级别的连接点,不支持在字段上的连接点(比如说,某一个字段发生了变化做出响应的这种动作)和构造器连接点。

    举例:

    通过注解为类引入新的功能:
    通过代理的方式,代理把委托的方法交给了另外一个类来实现,实现完了之后再交回给原来的类,实际上一个bean的实现被拆分到了多个类中。

    在xml中声明切面

        <aop:config> 顶层的AOP配置元素。 大多数的<aop:*>元素必须包含在<aop:config>元素内
        <aop:advisor> 定义AOP通知器
        <aop:declare-parents> 以透明的方式为被通知的对象引入额外的接口
        <aop:pointcut> 定义一个切点
        <aop:aspect> 定义一个切面
        <aop:aspectj-autoproxy> 启用@AspectJ注解驱动的切面
        
        <aop:before> 定义一个AOP前置通知
        <aop:after> 定义AOP后置通知(不管被通知的方法是否执行成功)
        <aop:after-returning> 定义AOP返回通知
        <aop:after-throwing> 定义AOP异常通知
        <aop:around> 定义AOP环绕通知

    XML可以吧一个POJO声明为一个切面,完成所有的Spring AOP的全部功能。

    一个配置的例子如下

           <bean id="as1" class="aspect.as1"></bean>   定义切面的bean
           <aop:config> AOP的配置都放在config下,可以定义多个aspect,对应多个切面
               <aop:aspect ref="as1">   aspect定义一个切面,指向POJO的bean
                   <aop:before
                           pointcut="execution(* Test.T1.doo(..)))"
                           method="Before"/>
                   <aop:after
                           pointcut="execution(* Test.T1.doo(..)))"
                           method="After" />
                   <aop:around
                           pointcut="execution(* Test.T1.doo(..)))"
                           method="Around" />
                   <aop:after-throwing
                           pointcut="execution(* Test.T1.doo(..)))"
                           method="Throw"/>
               </aop:aspect>
           </aop:config>
           <aop:aspectj-autoproxy/>  启动自动代理

    可以看到这里的PointCut都是一样的,可以定义出来一个PointCut进行简化,如下

          <aop:config>
               <aop:aspect ref="as1"> 在这里定义了PointCut,下面就可以直接使用了,也可以定义在config标签下面,这样所有的aspect都可以使用
                   <aop:pointcut id="pc" expression="execution(* Test.T1.doo(..)))"/>
                   <aop:before
                           pointcut-ref="pc"
                           method="Before"/>
                   <aop:after
                           pointcut-ref="pc"
                           method="After" />
                   <aop:around
                           pointcut-ref="pc"
                           method="Around" />
                   <aop:after-throwing
                           pointcut-ref="pc"
                           method="Throw"/>
               </aop:aspect>
           </aop:config>
  • 相关阅读:
    2716 [Violet 3] 天使玩偶
    BZOJ1017魔兽地图DotR 樹形DP
    BZOJ1016最小生成树计数 最小生成树 + 排列组合
    BZOJ1014火星人prefix Splay維護序列 + 字符串哈希
    BZOJ1010玩具裝箱Toy
    BZOJ1009GT考试 DP + KMP + 矩陣快速冪
    BZOJ1008[HNOI2008]越狱
    BZOJ1006神奇的国度 弦圖染色 最大勢算法
    BZOJ1005明明的烦恼 Prufer + 分解質因數 + 高精度
    poj2182(线段树求序列第k小)
  • 原文地址:https://www.cnblogs.com/Coder-Pig/p/7262687.html
Copyright © 2020-2023  润新知