Spring的AOP开发-基于xml配置的AOP

目录

基于xml配置的AOP

xml方式AOP快速入门

xml方式AOP配置详解

xml方式AOP原理剖析(后面再深入理解一下)

AOP底层两种生成Proxy的方法


基于xml配置的AOP

xml方式AOP快速入门

  • 在前面我们自己编写的AOP基础代码还存在一些问题,主要是
    • 被增强的范围写死了
    • 通知对象的方法在代码中写死了
    • 具体文章传送:Spring的AOP开发-AOP简介-CSDN博客
    •   

  •  我们可以通过配置文件解决上述问题
    • 配置增强的范围(配置目标对象)---切点表达式
    • 配置目标对象被哪些通知方法所增强,以及执行的顺序
    • 配置文件的设计,配置文件(注解)的解析工作,Spring已经帮我们封装好了。在java web中设计到一些该知识点,具体文章参照内容管理-CSDN创作中心,其中AOP相关知识点。

  • xml方式配置AOP的步骤
    • 导入AOP相关坐标
      •         <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.19</version></dependency>
    • 准备目标类、增强类、并配置给Spring管理
      • 还是参考往期文章,我是用的是注解的方式,只需要在配置文件中,设置组件扫描的范围即可。Spring的AOP开发-AOP简介-CSDN博客
    • 配置切点表达式(哪些方法被增强)
    • 配置织入(切点被哪些通知方法增强,是前置增强还是后置增强)

运行测试类

package com.example.Test;import com.example.Service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
}

 运行结果如下

xml方式AOP配置详解

  • xml配置AOP还是很简单的,具体细节如下
    • 切点表达式的配置方式
    • 切点表达式的配置语法
      • execution([访问修饰符] 返回类型 包名.类名.方法名(参数))
      • 访问修饰符可以省略不写
      • 返回值类型、某一级包名、类名、方法名可以使用表示*表示任意
      • 包名与类名之间使用单点.表示该包下的类,使用双点..表示该包及其子包下的类
      • 参数列表可以使用两个点..表示任意参数
      • 也可以参考java web专栏往期文章:AOP进阶-切入点表达式-execution-CSDN博客
    • 通知类型
      • AspectJ的通知由以下通知类型
      • 通知类型描述
        Before在目标方法执行之前执行的通知,用于进行准备工作或检查
        After在目标方法执行之后执行的通知,用于进行清理工作或资源释放,最终都会执行
        AfterReturning在目标方法正常执行并返回结果后执行的通知,用于处理返回值或记录结果,目标方法异常时,不再执行
        AfterThrowing在目标方法抛出异常后执行的通知,用于捕获和处理异常
        Around在目标方法执行前后都可以执行的通知,用于包裹目标方法的执行过程、控制和干预,目标方法异常时,环绕后方法不再执行
        StaticInitialization静态初始化代码块的通知,当类被加载时执行
        Initialization对象初始化代码块的通知,当对象被创建时执行
        FieldGet字段读取操作的通知,当访问字段时执行
        FieldSet字段赋值操作的通知,当修改字段值时执行
        MethodExecution方法执行的通知,包括Before、After、AfterReturning和AfterThrowing等通知的集合
      • 参考文章:AOP进阶-通知类型-CSDN博客,在该文章中使用的是注解方式来配置AOP。
      • 以下是通过xml方式来配置AOP前5种通知方式的代码示例
        • 5种通知方法        
          • package com.example.advice;import org.aspectj.lang.ProceedingJoinPoint;// 自定义增强类,内部提供增强方法
            public class MyAdvice {// todo 前置通知public void beforeAdvice() {System.out.println("前置通知");}// todo 后置通知public void afterAdvice() {System.out.println("后置通知");}// todo 环绕通知public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 前置通知System.out.println("环绕通知:前置通知");Object res = proceedingJoinPoint.proceed(); // 执行目标方法System.out.println("环绕通知中目标方法执行了");// 后置通知System.out.println("环绕通知:后置通知");return res;}// todo 异常通知public void afterThrowingAdvice() {System.out.println("异常抛出通知...出现异常才会执行");}// todo 最终通知public void endAdvice() {System.out.println("最终通知....怎么样都会通知");}}
            
        • 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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置目标类 --><bean id="userService" class="com.example.Service.ServiceImpl.UserServiceImpl"/><!-- 配置通知类 --><bean id="myAdvice" class="com.example.advice.MyAdvice"/><!-- AOP配置 --><aop:config><!-- 切点表达式,指定哪些方法被增强 --><aop:pointcut id="MyPointCut"expression="execution(void com.example.Service.ServiceImpl.UserServiceImpl.*(..))"/><!-- 配置织入,指定哪些切点与哪些通知进行结合 --><aop:aspect ref="myAdvice"><!--            前置通知--><aop:before method="beforeAdvice" pointcut-ref="MyPointCut"/><!--            后置通知--><aop:after-returning method="afterAdvice" pointcut-ref="MyPointCut"/><!--            环绕通知--><aop:around method="around" pointcut-ref="MyPointCut"></aop:around><!--            异常通知--><aop:after-throwing method="afterThrowingAdvice" pointcut-ref="MyPointCut"/><!--            最终通知--><aop:after method="endAdvice" pointcut-ref="MyPointCut"/></aop:aspect></aop:config>
            </beans>
            
        • 测试代码

          • package com.example.Test;import com.example.Service.UserService;
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
            }
            
          • 运行结果如下

        • 上述的运行结果也多多少少体现了各种通知类型的通知顺序, 具体可以参照文章:AOP进阶-通知顺序-CSDN博客,同时由于目标方法没有运行错误,所以,异常通知类无法通知,造出异常后:


  • AOP的配置两种方式
    • 使用<advisor>配置切面,使用较少,创建一个类,实现不同的类型的通知接口,从而不用在配置文件设置通知类型。
      • 实现通知接口的类(增强类,指定通知类型)
        • package com.example.advice;import org.springframework.aop.AfterReturningAdvice;
          import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class MyAdvice2 implements MethodBeforeAdvice, AfterReturningAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println("前置通知~~~~~~");}@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("后置通知~~~~~~");}}
          
      • 配置文件(该配置文件中并没有指定通知类型)
        • <?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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置目标类 --><bean id="userService" class="com.example.Service.ServiceImpl.UserServiceImpl"/><!-- 配置通知类 --><bean id="myAdvice2" class="com.example.advice.MyAdvice2"/><aop:config><aop:pointcut id="MyPointCut" expression="execution(* com.example.Service.ServiceImpl.UserServiceImpl.*(..))"/><aop:advisor advice-ref="myAdvice2" pointcut-ref="MyPointCut"></aop:advisor></aop:config></beans>
          
      • 测试类

        • package com.example.Test;import com.example.Service.UserService;
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMyAOP {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");UserService userService = applicationContext.getBean(UserService.class);userService.show1();}
          }
          
      • 运行结果如下

    • 使用<aspect>配置切面,上述配置中都是使用的该方法
  • Spring定义了一个Advice接口,实现该接口的类都可以作为通知类出现(一般都是实现其子类)
  • 两种配置方案的比较
    • 语法形式不同
      • advisor是通过实现接口来确认通知类型
      • aspect是通过配置确认通知类型,更加灵活
    • 可配置的切面数量不同
      • 一个advisor只能配置一个固定通知和一个切点表达式
      • 一个aspect可以配置多个通知和多个切点表达式
    • 使用场景不同 
      • 运行任意搭配情况下可以使用aspect进行配置
      • 如果通知类型单一、切面单一的情况下可以使用advisor进行配置
      • 在通知类型已经固定,不用人为指定通知类型时,可以使用advisor进行配置,例如后面会学习的Spring事务控制的配置。

xml方式AOP原理剖析(后面再深入理解一下)

  •  首先根据自定义命名空间进行解析,为标签指定解析器,该解析器向Spring容器中注入AspectJAwareAduisorAutoProxyCreator(其本质是一个beanPostProcessor,在对应的after方法中生成bean的代理对象存储到容器中)源码真的难看(记住过程)。

AOP底层两种生成Proxy的方法

  • 动态代理的实现的选择,在调用getProxy()方法时,我们可以选用的AopProxy接口有两个实现类,如上图,这两个都是动态生成代理对象的方式,一种是基于JDK的,一种是基于Cglib的
    • 代理技术使用条件配置方式
      JDK动态代理技术目标类有接口,是基于接口动态生成实现类的代理对象目标类有接口的情况下,默认方式
      Cglib动态代理技术目标类无接口且不能用final修饰,是基于被代理对象动态生成子对象为代理对象

      目标了无接口时,默认使用该方式;目标类有接口时,手动配置<aop:config proxy-target-class="true">强制使用Cglib方式

       
    • 代理对象实质上是接口实现类的对象。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/150353.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库——MySQL】(15)存储过程、存储函数和事务处理习题及讲解

目录 1. 题目1.1 存储过程1.2 存储函数1.3 事务处理 2. 解答2.1 存储过程2.2 存储函数2.3 事务处理 1. 题目 1.1 存储过程 创建表 RandNumber &#xff1a;字段&#xff1a;id 自增长&#xff0c; data int&#xff1b; 创建存储过程向表中插入指定个数的随机数&#xff08;1-…

【软件测试】自动化测试selenium(二)

文章目录 三. 掌握Selenium常用的API使用1. webdriver API2. 操作测试对象3. 添加等待4. 打印信息5. 浏览器的操作6. 键盘事件7. 鼠标事件8. 定位一组元素9. 多层框架/窗口定位10. 下拉框处理11. 弹窗处理12. 上传文件13. 关闭浏览器14. 切换窗口15. 截图操作 三. 掌握Selenium…

基于electron25+vite4创建多窗口|vue3+electron25新开模态窗体

在写这篇文章的时候&#xff0c;查看了下electron最新稳定版本由几天前24.4.0升级到了25了&#xff0c;不得不说electron团队迭代速度之快&#xff01; 前几天有分享一篇electron24整合vite4全家桶技术构建桌面端vue3应用示例程序。 https://www.cnblogs.com/xiaoyan2017/p/17…

【雷达原理】雷达测距原理及实现方法

目录 一、雷达测距原理1.1 基本原理1.2 实现方法1.3 与距离有关的概念 二、MATLAB仿真实验2.1 应用案例2.2 MATLAB代码 一、雷达测距原理 1.1 基本原理 我们知道&#xff0c;电磁波的传播速度为光速 c c c&#xff0c;若雷达与目标之间的距离为 R R R&#xff0c;则雷达发出…

QT实现tcp服务器客户端

服务器.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);// 此时&#xff0c;服务器已经成功进入监听状态…

LVGL_基础控件滑动条slider

LVGL_基础控件滑动条slider 1、创建滑动条控件 // 创建一个 slider 组件(对象)&#xff0c;他的父对象是活动屏幕对象 lv_obj_t *slider lv_slider_create(lv_scr_act()); LV_LOG_USER("lv_slider_get_value(slider) %d", lv_slider_get_value(slider));/* 设置位…

全屋灯具选购指南,如何选择合适的灯具。福州中宅装饰,福州装修

灯具装修指南 灯具就像我们家里的星星&#xff0c;在黑暗中带给我们明亮&#xff0c;可是灯具如果选择的不好&#xff0c;这个效果不仅体现不出来&#xff0c;还会让人觉得烦躁。 灯具到底该怎么选呢&#xff1f;装修灯具有哪些注意事项呢&#xff1f;给大家做了一个总结&#…

基于springboot的论坛网站

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 普通管理员管理 交流论坛 交流论坛评论 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了…

C语言qsort函数

排序qsort int int cmp(const void *a, const void *b) {return *(int *)a - *(int *)b;//先强转成int型&#xff0c;后解引用取值比较大小 }字符串数组 char a[] “hello world” //字符串数组&#xff0c;存放的是字符 int cmp(const void *a, const void *b) {return *(…

罗彻斯特大学探讨ChatGPT等人工智能将如何影响高等教育

人工智能聊天机器人ChatGPT持续引起互联网用户的热议&#xff0c;它能够回答关于各个领域的问题&#xff0c;创作歌曲、食谱&#xff0c;起草电子邮件等等。罗切斯特的教职员工和管理人员就他们如何处理 ChatGPT 以及它如何影响未来的教学和学习提出了他们的想法。 “让这项技…

快排(三种单趟排序法,递归非递归算法)

快排发明者:霍尔 (Sir Charles Antony Richard Hoare) 是一位英国计算机科学家。 计算机领域的爵士——托尼霍尔(Tony Hoare)(1934年1月11日出生),英文全称Sir Charles Antony Richard Hoare,常被称为Tony Hoare或者C. A. R. Hoare,1959年博士毕业于

idea清空缓存类

解决办法 网上有很多是让你去清空什么maven依赖&#xff0c;但假如这个项目是你不可以大刀阔斧的话 可以清空idea缓存 选择 Invalidate 开头的 然后全选 运行重启idea OK

FISCO BCOS(三十七)———FISCOBCOS应用开发,交易hash、区块高度的获取

这个需求怎么做? 交易hash的获取方式有很多,这里先介绍一种方式。 根据块高查询区块信息 https://webasedoc.readthedocs.io/zh_CN/latest/docs/WeBASE-Front/interface.html那我们如何知道现在的区块高度是多少? https://webasedoc.readthedocs.io/zh_CN/latest/docs/W…

VSCode Intellij IDEA CE 数据库连接

VSCode & Intellij IDEA CE 数据库连接 大概记一下现在正在用的几个工具/插件 VSCode VSCode 里面的工具我下载了很多&#xff0c;如果只是链接 MySQL 的话&#xff0c;可能用 Jun Han 这位大佬的 MySQL 就好了&#xff1a; 使用这个插件直接打开 .sql 文件单击运行就能…

nodejs+vue临沂特色产品销售平台elementui

从实际工作出发&#xff0c;对过去的临沂特色产品销售平台存在的问题进行分析&#xff0c;完善用户的使用体会。采用计算机系统来管理信息 提高了工作的效率。 随着信息化社会的形成和微电子技术日新月异的发展&#xff0c;临沂特色产品销售平台是针对目前临沂特色产品销售…

win10、win11彻底永久关闭自动更新的方法

win10、win11彻底永久关闭自动更新的方法 前言彻底关闭自动更新方法步骤一、禁用Windows Update服务二、在组策略里关闭Win10自动更新相关服务四、在注册表中关闭Win10自动更新 完结 前言 win系统的自动更新可谓是非常顽固&#xff0c;很多用户在网上试了各种关闭win系统自动更…

Ubuntu 20.04源码安装sysbench 1.0.20,源码安装sysstat v12.7.2

源码安装sysbench 1.0.20 参考的博客&#xff1a;《压测数据库1&#xff1a; Ubuntu 20 安装sysbench1.0.20》 sudo apt install -y automake libtool pkg-config下载依赖包&#xff0c;需要注意的是我这台计算机已经安装过mysql&#xff0c;所以我没有安装libmysqlclient-de…

【重拾C语言】六、批量数据组织(二)线性表——分类与检索(主元排序、冒泡排序、插入排序、顺序检索、对半检索)

目录 前言 六、批量数据组织——数组 6.1~3 数组基础知识 6.4 线性表——分类与检索 6.4.1 主元排序 6.4.2 冒泡排序 6.4.3 插入排序 6.4.4 顺序检索&#xff08;线性搜索&#xff09; 6.4.5 对半检索&#xff08;二分查找&#xff09; 算法比较 前言 线性表是一种常…

NPM 常用命令(九)

目录 1、npm link 1.1 使用语法 1.2 描述 2、npm login 2.1 描述 3、npm logout 3.1 描述 4、npm ls 4.1 使用语法 4.2 描述 5、npm org 5.1 使用语法 5.2 示例&#xff1a; 6、npm outdated 6.1 使用语法 6.2 描述 6.3 示例 7、npm owner 7.1 使用语法 7.2…

windows 任务计划自动提交 笔记到github 、gitee

一、必须有个git仓库托管到git上。 这个就不用说了&#xff0c;自己在github或者码云上新建一个仓库就行了。 二、创建自动提交脚本 这个bat脚本是在windows环境下使用的。 注意&#xff1a;windows定时任务下 调用自动提交git前&#xff0c;必须先进入该git仓库目录&#x…