欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于xml文件的AOP配置

程序员文章站 2024-01-20 16:26:04
基于xml文件的AOP配置 把通知类对象交割Spring来管理,即配置通知类对象 使用aop:config标签表明开始AOP的 ......

基于xml文件的aop配置

  • 把通知类对象交割spring来管理,即配置通知类对象

    <!-- 1、配置logger对象(这里是通知类) -->
    <bean id="logger" class="com.mypro.utils.logger"></bean>
  • 使用aop:config标签表明开始aop的配置

    <aop:config></aop:config>
  • 在aop:config标签内部使用aop:aspect标签表明配置切面

    • id属性:是给切面提供一个唯一标识

    • ref属性:指定通知类的bean的id

    <aop:config>
        <aop:aspect id="loggeradvice" ref="logger"></aop:aspect>
    </aop:config>
  • 在aop:aspect标签的内部使用对应的标签来配置通知的类型

    • 前置通知标签:aop:before

    • 后置通知标签:aop:after-returning

    • 异常通知标签:aop:after-throwing

    • 最终通知标签:aop:after

    • 上述通知标签共有的属性

      • method属性:用于指定通知类的方法

      • pointcut-ref属性:用于指定配置的切入点表达式的唯一标识的id

      • pointcut属性:用于指定切入点表达式,该表达式的含义是对业务层中的方法增强

        • 切入点表达式的标准格式:execution(访问修饰符 返回值类型 包名.包名..类名.方法名(参数列表)) 只针对某一个方法

        • 全通配符写法:

          * *..*.*(..)
        • 标准格式到全通配写法的演变

          • 访问修饰符可以省略

          • 返回值可以用通配符*代替,表示任意返回值                      *

          • 包名也可以用通配符代替,有几个包就有几个                              * *

          • 包名也可以简化:..表示当前包及所有子包                                    * *..

          • 类名也可以用通配符*代替,表示任意类 *                                      * *..*

          • 方法名也可以用通配符代替,表示任意方法                                   * *..*.*

          • 参数列表

            • 可以是基本数据类型 示例 int

            • 可以是引用类型写包名.类名的方式 示例 java.lang.string

            • 可以使用通配符.表示任意数据类型,但是必须有参数       * *..*.*(.)

            • 可以再添加一个通配符.表示有无参数                                * *..*.*(..)

          • 可以根据需求添加需要的通配符

    • 配置切入点表达式

      • 标签:aop:pointcut

      • 属性:id唯一标识,expression配置的表达式

      • 分类

        • 将aop:pointcut标签放置在aop:aspect标签内部的任何位置,只限于当前切面使用

        • 将aop:pointcut标签只能放置在第一个aop:aspect标签外部的上方,任何切面都可以使用

      <aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:point>

      完整的aop配置文件

      <bean id="logger" class="com.mypro.service.impl.wordsserviceimpl"></bean>
      <aop:config>
          <aop:aspect id="loggeradvice" ref="logger">
              <aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:point>
              <aop:before method="beforeinfo" pointcut-ref="pt1"></aop:before>
              <aop:after-returning method="afterreturninginfo" pointcut-ref="pt1"></aop:after-returning>
              <aop:after-throwing method="afterthrowinginfo" pointcut-ref="pt1"></aop:after-throwing>
              <aop:after method="afterinfo" pointcut-ref="pt1"></aop:after>
          </aop:aspect>
      </aop:config>
    • 环绕通知标签:aop:around。属性和其他通知标签的属性即作用一样,而环绕通知的功能就是通过编码完成上述4中通知标签的事情,而只需要在xml文件配置这一个环绕通知的标签即可,编码就在通知类中实现

      <bean id="logger" class="com.mypro.service.impl.wordsserviceimpl"></bean>
      <aop:config>
          <aop:aspect id="loggeradvice" ref="logger">
              <aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:pointcut>
              <aop:around method="aroundinfo" poinitcut-ref="pt1"></aop:around>
          </aop:aspect>
      </aop:config>

      然后在通知类中(这里是logger类)的aroundinfo方法编写类似上述四种通知的功能。

      分析:通过动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的方法没有

      解决:spring框架为我们提供了一个接口,proceedingjoinpoint,该接口有一个proceed方法,此方法就相当于明确调用切入点方法,该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类调用

      import org.aspectj.lang.proceedingjoinpoint;
      public class logger{
          public object aroundinfo(){
              object rtvalue = null;
              try{
                  system.out.println("前置通知");
                  // 得到方法执行时所需的参数
                  object[] args = pjp.getargs();
                  // 明确调用业务层方法(切入点方法)
                  rtvalue = pjp.proceed(args);
                  system.out.println("后置通知");
                  return rtvalue;
              }catch(throwable t){      // 必须是用throwable捕捉异常
                  system.out.println("异常通知");
                  throw new runtimeexception(t);
              }finally{
                  system.out.println("最终通知");
              }
          }
      }