Spring boot AOP通过XML配置文件声明切面的方法

发布时间:2020-06-23 09:21:05 作者:清晨
来源:亿速云 阅读:462

不懂Spring boot AOP通过XML配置文件声明切面的方法?其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。

下面先列出 XML 中声明 AOP 的常用元素:

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

XML 配置文件中切点指示器

在XML配置文件中,切点指示器表达式与通过注解配置的写法基本一致,区别前面有提到,即XML文件中需要使用 “and”、“or”、“not”来表示 “且”、“或”、“非”的关系。

XML 文件配置 AOP 

新建OrderXmlAop.java:

package com.example.demo.aop;
 
public class OrderXmlAop {
 
  /**
   * @description 在连接点执行之前执行的通知
   */
  public void doBefore(){
    System.out.println("阿里阿塞哟!");
  }
 
  /**
   * @description 在连接点执行之后执行的通知(返回通知和异常通知的异常)
   */
  public void doAfter(){
    System.out.println("after!");
  }
 
 
  /**
   * @description 在连接点执行之后执行的通知(返回通知)
   */
   public void doAfterReturning(){
 
     System.out.println("返回通知:AfterReturning");
   }
 
  /**
   * @description 在连接点执行之后执行的通知(异常通知)
   */
  public void doAfterThrowing(){
   System.out.println("异常通知:AfterThrowing");
   }
}

在 Resource 目录下新建一个配置文件 aoporder.xml :

<&#63;xml version="1.0" encoding="UTF-8"&#63;>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="wmzService" class="com.example.demo.service.impl.WMZServiceImpl"></bean>
  <bean id="zsService" class="com.example.demo.service.impl.ZSServiceImpl"></bean>
  <!-- 切面类 -->
  <bean id="OrderXmlAop" class="com.example.demo.aop.OrderXmlAop"></bean>
 
  <!-- Aop配置 -->
  <aop:config proxy-target-class="true">
 
    <!-- 切面 -->
    <aop:aspect ref="OrderXmlAop">
      <!-- 前置通知: 在目标方法调用前执行 -->
      <aop:before pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doBefore"/>
      <!-- 后置通知: -->
      <aop:after pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfter"/>
      <!-- 返回后通知 -->
      <aop:after-returning pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfterReturning"/>
      <!-- 异常通知 -->
      <aop:after-throwing pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfterThrowing"/>
    </aop:aspect>
  </aop:config>
</beans>

新建 TakeXmlController.java

package com.example.demo.controller;
 
import com.example.demo.entity.Response;
import com.example.demo.entity.ResponseResult;
import jdk.internal.org.objectweb.asm.tree.analysis.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.service.TakeawayService;
@RestController
@RequestMapping("/api")
 
public class TakeXmlController {
 
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("aoporder.xml");
  @RequestMapping("/orderxml")
  public ResponseResult Ordexml()
  {
    /**
    ** 注意 此处的getBean(name)中的name 必须要和aoporder.xml 配置的bean节点上的id 保持一致
     * 如: <bean id="wmzService" class="com.example.demo.service.impl.WMZServiceImpl"></bean>
     * TakeawayService wmzService=(TakeawayService)context.getBean("wmzService");
     */
    TakeawayService wmzService=(TakeawayService)context.getBean("wmzService");
    String wmz= wmzService.Order(12);
    System.out.println(wmz);
    TakeawayService zsService=(TakeawayService)context.getBean("zsService");
    String zs=zsService.Order(4396);
    System.out.println(zs);
    return Response.makeOKRsp(wmz+";"+zs);
  }
}

运行结果:

Spring boot AOP通过XML配置文件声明切面的方法

声明环绕通知

修改OrderXmlAop.java:

package com.example.demo.aop;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public class OrderXmlAop {
 
  /**
   * @description 在连接点执行之前执行的通知
   */
  public void doBefore(){
    System.out.println("阿里阿塞哟!");
  }
 
  /**
   * @description 在连接点执行之后执行的通知(返回通知和异常通知的异常)
   */
  public void doAfter(){
    System.out.println("after!");
  }
 
 
  /**
   * @description 在连接点执行之后执行的通知(返回通知)
   */
   public void doAfterReturning(){
 
     System.out.println("返回通知:AfterReturning");
   }
 
  /**
   * @description 在连接点执行之后执行的通知(异常通知)
   */
  public void doAfterThrowing(){
   System.out.println("异常通知:AfterThrowing");
   }
 
  /**
   * @description 在连接点执行之后执行的通知(异常通知)
   */
  public void doAround(ProceedingJoinPoint pj) {
    try {
      System.out.println("Around 调用方法前 ");
      pj.proceed();
      System.out.println("Around 调用方法后");
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    }
  }
}

aoporder.xml:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="wmzService" class="com.example.demo.service.impl.WMZServiceImpl"></bean>
  <bean id="zsService" class="com.example.demo.service.impl.ZSServiceImpl"></bean>
  <!-- 切面类 -->
  <bean id="OrderXmlAop" class="com.example.demo.aop.OrderXmlAop"></bean>
 
  <!-- Aop配置 -->
  <aop:config proxy-target-class="true">
 
    <!-- 切面 -->
    <aop:aspect ref="OrderXmlAop">
      <!-- 环绕通知 -->
      <aop:around pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAround"/>
      <!-- 前置通知: 在目标方法调用前执行 -->
      <aop:before pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doBefore"/>
      <!-- 后置通知: -->
      <aop:after pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfter"/>
      <!-- 返回后通知 -->
      <aop:after-returning pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfterReturning"/>
      <!-- 异常通知 -->
      <aop:after-throwing pointcut="execution(public * com.example.demo.service.TakeawayService.*(..)))" method="doAfterThrowing"/>
    </aop:aspect>
  </aop:config>
</beans>

运行结果:

Spring boot AOP通过XML配置文件声明切面的方法

结果和我们预期的一致,环绕通知通过xml配置成功。

XML 文件配置声明切点 

在上面的例子中,我们发现有切点表达式多次重复出现,那么可不可以和aspectj配置一样,单独声明切点,后面复用,答案是当然可以。如下修改aoporder.xml:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="wmzService" class="com.example.demo.service.impl.WMZServiceImpl"></bean>
  <bean id="zsService" class="com.example.demo.service.impl.ZSServiceImpl"></bean>
  <!-- 切面类 -->
  <bean id="OrderXmlAop" class="com.example.demo.aop.OrderXmlAop"></bean>
 
  <!-- Aop配置 -->
  <aop:config proxy-target-class="true">
    <!-- 切点 -->
    <aop:pointcut id="point" expression="execution(public * com.example.demo.service.TakeawayService.*(..)))"/>
    <!-- 切面 -->
    <aop:aspect ref="OrderXmlAop">
      <!-- 环绕通知 -->
      <aop:around pointcut-ref="point" method="doAround"/>
      <!-- 前置通知: 在目标方法调用前执行 -->
      <aop:before pointcut-ref="point" method="doBefore"/>
      <!-- 后置通知: -->
      <aop:after pointcut-ref="point" method="doAfter"/>
      <!-- 返回后通知 -->
      <aop:after-returning pointcut-ref="point" method="doAfterReturning"/>
      <!-- 异常通知 -->
      <aop:after-throwing pointcut-ref="point" method="doAfterThrowing"/>
    </aop:aspect>
  </aop:config>
</beans>

修改后执行结果:

Spring boot AOP通过XML配置文件声明切面的方法

XML文件配置为通知传递参数

修改OrderXmlAop.java

public String doAround(ProceedingJoinPoint pj,double price) {
    try {
      System.out.println("Around 调用方法前 ");
      pj.proceed();
      if(price>=4396)
      {
        System.out.println("zs下单超过了4399,赠送一份鲜果饮汇源牌饮料");
        return "爆浆牛丸和饮料";
      }
      System.out.println("Around 调用方法后");
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    }
    return "爆浆牛丸";
  }

修改aoporder.xml

<&#63;xml version="1.0" encoding="UTF-8"&#63;>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="wmzService" class="com.example.demo.service.impl.WMZServiceImpl"></bean>
  <bean id="zsService" class="com.example.demo.service.impl.ZSServiceImpl"></bean>
  <!-- 切面类 -->
  <bean id="OrderXmlAop" class="com.example.demo.aop.OrderXmlAop"></bean>
 
  <!-- Aop配置 -->
  <aop:config proxy-target-class="true">
    <!-- 切点 -->
    <aop:pointcut id="point" expression="execution(com.example.demo.service.TakeawayService.Order(double)) and args(price) and bean(zsService)"/>
    <!-- 切面 -->
    <aop:aspect ref="OrderXmlAop">
      <!-- 环绕通知 -->
      <aop:around pointcut-ref="point" method="doAround"/>
    </aop:aspect>
  </aop:config>
</beans>

感谢你能够认真阅读完这篇文章,希望小编分享Spring boot AOP通过XML配置文件声明切面的方法内容对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,遇到问题就找亿速云,详细的解决方法等着你来学习!

推荐阅读:
  1. Spring Boot web自己的整理
  2. spring boot与spring mvc的区别是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot aop spring boo

上一篇:在python字典中添加元素的方法

下一篇:redis实现分布式锁的方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》