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