AOP

作者: 茶酒qqq | 来源:发表于2020-01-20 20:58 被阅读0次

    AOP

    spring的IOC基于反射,通过读取配置文件获取对象的全限定类名,然后用反射创建,相当于是把BeanFactory包装了,扩展了。

    而spring的AOP是基于动态代理,把动态代理包装起来,我们通过xml配置AOP使用,减少重复代码,减少程序耦合,帮助维护。

    AOP术语

    • 连接点(join-point):业务层中所有的方法都是连接点
    • 切入点(point-cut):业务层中被增强的方法
    • 通知(advice):拦截到连接点后要做的事情
      • 前置通知:method.invoke前的东西
      • 后置通知:method.invoke后的东西
      • 异常通知:catch里的东西
      • 最终通知:finally里的东西
      • 环绕通知:整个invoke方法在执行时是环绕通知,在环绕通知中有明确的的切入点方法调用(metho.invoke())
    • 目标对象(target):被代理对象
    • 织入(weaving):代理的过程
    • 代理(Proxy):产生的代理对象
    • 切面(Aspect):切入点和通知的结合(就是你invoke方法里写的东西)

    学习Spring中AOP要明确的事

    开发阶段(我们做的):

    • 编写核心业务:大部分程序员来做
    • 把公共代码抽出来,制作成通知(开发阶段最后再做):AOP编程人员做
    • 在配置文件中,声明切入点和通知的关系,即切面:AOP编程人员做

    运行阶段(Spring框架完成的):

    • Spring框架监控切入点方法的执行,一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应功能织入,完成完整的代码逻辑运行。

    spring中基于XML的AOP配置步骤

    1. 把业务层Bean和通知Bean交给spring管理

      <bean id="accountService" class="com.chajiu.service.Impl.AccountService"></bean>
      
      <bean id="logger" class="com.chajiu.log.Logger"></bean>
      
    2. 使用aop:config标签表明开始AOP的配置

    3. 使用aop:aspect表明配置切面

      • id属性:给切面一个唯一标识
      • ref属性:标识指定的通知类Bean的id
    4. aop:aspect标签内部使用各种通知类型的标签配置通知的类型

      ​ 比如配置前置通知,使用:asp:before

      • method:用于指定通知类中的哪个方法是前置通知
      • pointcut:用于指定切入点表达式,也就是指定切入点是哪个类的哪个方法。
    5. aop:pointcut可以把切入点单独拿出来,使用id表示唯一名称,使用exception指定表达式

      <aop:config>
          <aop:pointcut id="p1" expression="execution(* com.chajiu.service.Impl.*.*(..) )"/>
          <aop:aspect id="logAdvice" ref="logger">
              <aop:before method="logSt" pointcut-ref="p1"></aop:before>
              <aop:after-returning method="logEd" pointcut-ref="p1"></aop:after-returning>
          </aop:aspect>
      
      </aop:config>
      

    切入点表达式的写法:

    • 关键字:execution(表达式)

    • 表达式:

      • 访问修饰符 返回值 包名.包名.包名.包名...类名.方法名(参数列表)
      • public void com.chajiu.service.impl.AccountServiceImpl.saveAccount()
    • 访问修饰符可以省略

      • void com.chajiu.service.impl.AccountServiceImpl.saveAccount()
    • 返回值可以使用通配符* 表示任意返回值

    • 包名可以使用通配符* 表示任意包,但是有几级包写几个*

    • 包名可以用..表示当前包及其子包

      • * com..AccountServiceImpl.saveAccount()
    • 类名和方法名都可以用*匹配(所以括号前通常是 *.*)

      • * *..*.*()
    • 参数列表

      • 可以直接写数据类型
        • 基本数据类型使用本身 int
        • 引用类型需要全限定类名 java,lang,String
      • 可以使用*匹配任意数据类型,但是不能为空
      • 使用..表示有无参数均可,有参数可以是任意参数
    • 全通配写法

      • * *..*.*(..)
    • 实际开发中切入点表达式通常写为:

      • 业务层的所有方法
        • * com.chajiu.service.impl.*.*(..)

    相关文章

      网友评论

          本文标题:AOP

          本文链接:https://www.haomeiwen.com/subject/kshszctx.html