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

通过 XML 配置文件声明

在前两篇博文和示例中,我们已经展示了如何通过注解配置去声明切面,下面我们看看如何在 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 :

<?xml version="1.0" encoding="UTF-8"?>
<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);
 }
}

运行结果:

声明环绕通知

修改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:

<?xml version="1.0" encoding="UTF-8"?>
<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>

运行结果:

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

XML 文件配置声明切点 

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

<?xml version="1.0" encoding="UTF-8"?>
<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>

修改后执行结果:

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

<?xml version="1.0" encoding="UTF-8"?>
<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>

总结

本文主要通过XML配置文件使用 Spring AOP进行编程,和上一篇的注解方式两者联系起来对于刚入门的应该多多少少还是有点帮助的吧,针对于aop 通过三篇博客简单的描述,相信大家对此都有点印象了,记录了 AOP 的编程思想,然后介绍了 Spring 中 AOP 的相关概念,以及通过注解方式和XML配置文件两种方式使用 Spring AOP进行编程。所以对aop的博文就简单到这儿了,有人要问了,aop里面的代理啊还有各种各样的,如果真要吧aop重头到尾来一遍的话,这个系列可以单独提出来一个专栏了,所以后面的博文应该都是围绕连接数据库,记录日志,接入swagger文档等功能相继展开了。在此过程中,我有错误使用的地方,或者表达有问题,还请您及时告知,本人会在第一时间予以改正。最后在祝大家周末愉快,C Y L L

(0)

相关推荐

  • Spring 配置文件XML头部文件模板实例详解

    普通spring配置文件模板: <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.s

  • Spring根据XML配置文件 p名称空间注入属性的实例

    要生成对象并通过名称空间注入属性的类 代码如下: package com.swift; public class User { private String userName; public void setUserName(String userName) { this.userName = userName; } public String fun() { return "User's fun is ready."+this.userName; } } XML配置文件写法如下: &

  • Spring根据XML配置文件注入属性的方法

    方法一使用setter方法 package com.swift; public class Book { private String bookName; public void setBook(String bookName) { this.bookName = bookName; } @Override public String toString() { return "Book [book=" + bookName + "]"; } } 在Spring框架中

  • spring web.xml指定配置文件过程解析

    这篇文章主要介绍了spring web.xml指定配置文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-beans.xml</param-value> </context-param> 指定

  • spring如何实现两个xml配置文件间的互调

    这篇文章主要介绍了spring如何实现两个xml配置文件间的互调,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先建两个测试类 package soundsystem; public class Dog { private String Cry; private Cat Cat; public void setCry(String cry) { Cry = cry; } public void setCat(soundsystem.Cat c

  • spring*.xml配置文件明文加密的实现

    说明:客户要求spring*.xml中Oracle/Redis/MongoDB的IP.端口.用户名.密码不能明文存放,接到需求的我,很无奈,但是还是的硬着头皮搞 系统架构:spring+mvc(Oracle是用jdbc自己封装的接口) 1.数据库配置文件加密 原xml配置 <?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/

  • Spring 加载多个xml配置文件的原理分析

    目录 示例 spring-configlication.xml: spring-config-instance-factory.xml java示例代码 实现 AbstractRefreshableConfigApplicationContext AbstractApplicationContext AbstractRefreshableApplicationContext AbstractXmlApplicationContext 示例 先给出两个Bean的配置文件: spring-confi

  • Spring手动生成web.xml配置文件过程详解

    步骤一: 找到自己所创建的项目名,效果如下: 步骤二: 右击自己所创建的项目---->Java EE Tools---->点击Generate Deployment Descriptor Stub,完成这几步,即可,效果如下: 最后,就会生成web.xml配置文件会在WebContent-->WEB-INF文件中,如下: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

  • 如何在spring官网查找XML基础配置文件

    这篇文章主要介绍了如何在spring官网查找XML基础配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.首先进入spring官网:https://spring.io/: 2.然后点击projects目录,出现如下页面: 3.点击spring framework进入spring框架页面,点击Learn,点击Reference Doc如图: 4.进入doc页面后,点击Core,如图: 5.进入core页面后,点击1.2.1 Configu

  • spring是如何解析xml配置文件中的占位符

    前言 我们在配置Spring Xml配置文件的时候,可以在文件路径字符串中加入 ${} 占位符,Spring会自动帮我们解析占位符,这么神奇的操作Spring是怎么帮我们完成的呢?这篇文章我们就来一步步揭秘. 1.示例 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); applicationContext.setConfigLocation("${java.versi

  • Spring主配置文件(applicationContext.xml) 导入约束详解

    eclipse导入Spring配置文件约束  Windows-Preference-XML-XMLCatalog 点 Add 选File System 下spring的解压包下的schema文件夹,选beans,然后选择spring对应的版本的xsd文件 选择指定xsd文件,再Key的路径后面添加"/spring-beans-4.2.xsd"点ok 创建applicationContext.xml   写根元素 <beans></beans> Add导入XSI,

  • 详解spring applicationContext.xml 配置文件

    applicationContext.xml 文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http

随机推荐