演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP

news2024/7/6 4:24:23

😀前言
本篇的Spring-AOP系类文章第五篇讲解了演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 💖演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP
    • 💞AOP-切入点表达式重用
      • 🤔应用实例
        • ● 切入点表达式重用
        • ● 应用案例: 在原来的代码上修改即可
        • 测试AopJoinPointTest.java
    • 🥰AOP-切面优先级问题
      • 😉应用实例
        • ● 切面优先级问题:
        • ● 基本语法:
      • ● 案例说明
        • 测试
      • 💥注意事项和细节说明
    • 😊AOP-基于 XML 配置 AOP
      • 😀代码示例
        • 实现步骤
        • 具体实现
      • 测试
    • 😄总结

💖演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP

💞AOP-切入点表达式重用

🤔应用实例

● 切入点表达式重用

为了统一管理切入点表达式,可以使用切入点表达式重用技术。

● 应用案例: 在原来的代码上修改即可

  1. 修改SmartAnimalAspect.java

image-20230805173029980


    /**
     * 使用切面编程来替代原来的动态代理类,机制是一样的.
     * @author Administrator
     */
    @Aspect //表示这个类是一个切面类
    @Component //需要加入到IOC 容器
    public class SmartAnimalAspect {
        //=====AOP-切入点表达式重用start ======
        /*
         * 这样定义的一个切入点表达式,就可以在其它地方直接使用
         */
        @Pointcut(value = "execution(public float
                com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))")
        public void myPointCut() {
        }
        // @Before(value="execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))")
        @Before(value = "myPointCut()")
        public void showBeginLog(JoinPoint joinPoint) { //前置方法
            //得到方法的签名
            // 调用前置通知对应的方法签名: float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float)
            Signature signature = joinPoint.getSignature();
            //得到方法名.
            String method_name = signature.getName();
            //得到参数
            Object[] args = joinPoint.getArgs();
            System.out.println("前置通知" + "--调用的方法是" + method_name + "--参数是
                    --" + Arrays.asList(args));
        }
        //@After(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))")
        @After(value = "myPointCut()")
        public void showFinallyEndLog() {
            System.out.println("最终通知-- AOP-切入点表达式重用");
        }
        /**
         * returning = "res", Object res 名称保持一致
         * @param joinPoint
         * @param res 调用getSum() 返回的结果
         */
        @AfterReturning(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))",
        returning = "res")
        public void showSuccessEndLog(JoinPoint joinPoint, Object res) {
            System.out.println("返回通知" + "--结果是--" + res);
        }
        @AfterThrowing(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))", throwing = "throwable")
        public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {
            System.out.println("异常通知-- 异常信息--" + throwable);
        }
        //=====AOP-切入点表达式重用end ======

测试AopJoinPointTest.java

image-20230805173406696

🥰AOP-切面优先级问题

😉应用实例

● 切面优先级问题:

如果同一个方法,有多个切面在同一个切入点切入,那么执行的优先级如何控制.

● 基本语法:

@order(value=n) 来控制 n值越小,优先级越高

● 案例说明

  1. 创建\SmartAnimalAspect2.java

@Aspect //表示这个类是一个切面类
@Order(value = 2)
@Component //需要加入IOC 容器
public class SmartAnimalAspect2 {
    /*
     * 这样定义的一个切入点表达式,就可以在其它地方直接使用
     */
    @Pointcut(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))")
    public void myPointCut() {
    }
    @Before(value = "myPointCut()")
    public void showBeginLog(JoinPoint joinPoint) {
        System.out.println("前置通知SmartAnimalAspect2 showBeginLog");
    }
    @AfterReturning(value = "myPointCut()", returning = "res")
    public void showSuccessEndLog(JoinPoint joinPoint, Object res) {
        System.out.println("返回通知SmartAnimalAspect2 showSuccessEndLog");
    }
    @AfterThrowing(value = "myPointCut()", throwing = "throwable")
    public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {
        System.out.println("异常通知SmartAnimalAspect2 showExceptionLog");
    }
    @After(value = "myPointCut()")
    public void showFinallyEndLog() {
        System.out.println("最终通知SmartAnimalAspect2 showFinallyEndLog");
    }
}
  1. 修改SmartAnimalAspect.java

image-20230805173922064

测试

image-20230805174346020

  1. 如何理解输出的信息顺序,类似Filter 的过滤链式调用机制. (示意图-就比较清楚了.)

💥注意事项和细节说明

如何理解输出的信息顺序,类似 Filter 的过滤链式调用机制. (示意图-就比较清楚了.)

  1. 不能理解成:优先级高的每个消息通知都先执行,这个和方法调用机制(和 Filter 过滤器链式调用类似)

  2. 如何理解执行顺序

img

😊AOP-基于 XML 配置 AOP

● 基本说明:

前面我们是通过注解来配置 aop 的,在 spring 中,我们也可以通过 xml 的方式来配置 AOP

😀代码示例

实现步骤

  1. 创建包com.wyxedu.spring.aop.xml , SmartAnimalable.java 和SmartDog.java 从其它包拷贝即可
  2. 创建SmartAnimalAspect.java , 从com.wyxedu.spring.aop 包拷贝,并去掉所有注解

具体实现

  1. 创建接口SmartAnimalable
public interface SmartAnimalable {
    //求和
    float getSum(float i, float j);
    //求差
    float getSub(float i, float j);
}
  1. 创建SmartAnimalAspect类注意没有注解
public class SmartAnimalAspect {


    public void showBeginLog(JoinPoint joinPoint) {
        //通过连接点对象joinPoint 可以获取方法签名
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect-XML配置-切面类showBeginLog()[使用的myPointCut()]-方法执行前-日志-方法名-" + signature.getName() + "-参数 "
                + Arrays.asList(joinPoint.getArgs()));
    }

    public void showSuccessEndLog(JoinPoint joinPoint, Object res) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect-XML配置-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res);
    }


    public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect-XML配置-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable);
    }

    public void showFinallyEndLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect-XML配置-切面类showFinallyEndLog()-方法最终执行完毕-日志-方法名-" + signature.getName());
    }
}
  1. 创建SmartDog注意没有注解
public class SmartDog implements SmartAnimalable {
    @Override
    public float getSum(float i, float j) {
        float result = i + j;
        //result = 1 / 0; //模拟一个算术异常
        System.out.println("方法内部打印result = " + result);
        return result;
    }

    @Override
    public float getSub(float i, float j) {
        float result = i - j;
        System.out.println("方法内部打印result = " + result);
        return result;
    }
}
  1. 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:context="http://www.springframework.org/schema/context"
       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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--使用XML配置,完成AOP编程-->
    <!--配置一个切面类对象-bean-->
    <bean class="com.spring.aop.xml.SmartAnimalAspect" id="smartAnimalAspect"/>
    <!--配置一个SmartDog对象-bean-->
    <bean class="com.spring.aop.xml.SmartDog" id="smartDog"/>
    <!--配置切面类, 细节一定要引入 xmlns:aop-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="myPointCut" expression="execution(public float com.spring.aop.xml.SmartDog.getSum(float, float)))"/>
        <!--配置切面的前置,返回, 异常, 最终通知-->
        <aop:aspect ref="smartAnimalAspect" order="10">
            <!--配置前置通知-->
            <aop:before method="showBeginLog" pointcut-ref="myPointCut"/>
            <!--返回通知-->
            <aop:after-returning method="showSuccessEndLog" pointcut-ref="myPointCut" returning="res"/>
            <!--异常通知-->
            <aop:after-throwing method="showExceptionLog" pointcut-ref="myPointCut" throwing="throwable"/>
            <!--最终通知-->
            <aop:after method="showFinallyEndLog" pointcut-ref="myPointCut"/>
            <!--配置环绕通知-->
            <!--<aop:around method=""/>-->
        </aop:aspect>
    </aop:config>
</beans>

测试

public class AopAspectjXMLTest {

    @Test
    public void testAspectByXML() {

        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans09.xml");
        SmartAnimalable smartAnimalable =
                ioc.getBean(SmartAnimalable.class);

        smartAnimalable.getSum(10, 2);
    }

}

😄总结

本文详细的讲解了spring AOP的切入表达式重用和AOP优先级问题以及AOP怎么实现基于xml的aop

😍Spring-AOP系类文章
第一篇-> Spring-AOP的基本介绍以及通过先动态代理方式实现

第二篇-> Spring-动态代理深入了解

第三篇-> 再次分析-提出 Spring AOP-真正的AOP

第四篇-> spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知

😁热门专栏推荐
想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集
linux合集
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

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

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

相关文章

c++11 标准模板(STL)(std::basic_fstream)(一)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_fstream : public std::basic_iostream<CharT, Traits> 类模板 basic_fstream 实现基于文件的流上的高层输入/输出。它将 std::basic_i…

Linux常用命令——dnf命令

在线Linux命令查询工具 dnf 新一代的RPM软件包管理器 补充说明 DNF是新一代的rpm软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近&#xff0c;它取代了yum&#xff0c;正式成为 Fedora 22 的包管理器。 DNF包管理器克服了YUM包管理器的一些瓶颈&#xff0c;提升…

docker-compose 部署elk,别找了,这是最好的教程

通过docker-compose编排一系列环境进行一键快速部署运行&#xff0c;小白运维神器。 # 安装git命令&#xff1a; yum install -y git git clone https://gitee.com/zhengqingya/docker-compose.git cd docker-compose/Linux环境部署见每个服务下的run.md&#xff1b; eg: Linu…

使用webpack插件webpack-dev-server 出现Cannot GET/的解决办法

问题描述 文档地址深入浅出webpack 使用 DevServer运行webpack&#xff0c;跑起来之后提示Cannot GET/&#xff1a; 解决方案&#xff1a; 查阅官方文档 根据目录结构修改对应的配置&#xff1a; 然后就可以成功访问&#xff1a;

windows安装docker 异常解决

Docker for Windows 安装Docker for Windows报错信息&#xff1a;Docker Desktop requires Windows 10 Pro/Enterprise/Home (18363). 解决方式 1.更新 Windows 系统版本Windows10Upgrade9252.exe 下载地址下载完运行 Windows10Upgrade9252.exe更新完&#xff0c;安装 Docke…

html 计算器界面

其他链接&#xff1a; https://www.freecodecamp.org/news/how-to-build-an-html-calculator-app-from-scratch-using-javascript-4454b8714b98/ https://codepen.io/pen/tour/welcome/start 下面展示一些 内联代码片。 <!DOCTYPE html> <html lang"en">…

使用Spring Initializr方式构建Spring Boot项目

除了可以使用Maven方式构建Spring Boot项目外&#xff0c;还可以通过Spring Initializr方式快速构建Spring Boot项目。从本质上说&#xff0c;Spring lnitializr是一个Web应用&#xff0c;它提供了一个基本的项目结构&#xff0c;能够帮助我们快速构建一个基础的Spring Boot项目…

Effective Java笔记(28)列表优于数组

数组与泛型相比&#xff0c;有两个重要的不同点 。 首先&#xff0c;数组是协变的&#xff08; covariant &#xff09; 。 这个词听起来有点吓人&#xff0c;其实只是表示如果 Sub 为 Super 的子类型&#xff0c;那么数组类型 Sub[ ]就是Super[ ]的子类型。 相反&#xff0c;泛…

HTML 元素的 class 和 id 属性有何区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 唯一性⭐ 选择器权重⭐ JS操作⭐ CSS和JavaScript引用⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

【网络】自定义协议 | 序列化和反序列化 | 以tcpServer为例

本文首发于 慕雪的寒舍 以tcpServer的计算器服务为例&#xff0c;实现一个自定义协议 阅读本文之前&#xff0c;请先阅读 tcpServer 本文完整代码详见 Gitee 1.重谈tcp 注意&#xff0c;当下所对tcp的描述都是以简单、方便理解起见&#xff0c;后续会对tcp协议进行深入解读 …

威纶通触摸屏插入U盘自动登录,拔出U盘自动注销

威纶通触摸屏官网的 Easybuilder Pro 手册 第十章有该功能的使用方法。 在工程文件中设置好账号密码&#xff0c;启用USB登录。 将 U 盘插入电脑&#xff0c;在 EBPro 的安装路径下找到 Administrator Tools&#xff0c;打开 设置账号密码&#xff0c;储存到U盘&#xff0c;之…

你知道函数栈帧的创建和销毁吗?

文章目录 前言观图有感一、概述二、寄存器三、汇编指令四、函数栈帧的创建4.1 main函数栈帧的创建push ebpmov ebp,espsub esp,0E4hpush ebx / esi /edilea edi,[ebp-24h] 、mov ecx,9、mov eax,0CCCCCCCCh、rep stos dword ptr es:[edi]main函数中变量的创建 4.2 在main函数中…

Focal and Global Knowledge Distillation for Detectors(CVPR 2022)原理与代码解析

paper&#xff1a;Focal and Global Knowledge Distillation for Detectors official implementation&#xff1a;https://github.com/yzd-v/FGD 存在的问题 如图1所示&#xff0c;前景区域教师和学生注意力之间的差异非常大&#xff0c;背景区域则相对较小。此外通道注意力…

【错误记录】Uncaught SyntaxError: Not available in legacy mode

错误记录&#xff1a;Uncaught SyntaxError: Not available in legacy mode 错误描述&#xff1a;在vite脚手架项目当中&#xff0c;使用vue-i18n插件进行国际化多语言时&#xff0c;报错 解决方案&#xff1a; 在引入vue-i18n 处&#xff0c;添加 legacy: false 如果对项目…

玩转Vue3:计算属性和监视属性深度解析

计算属性computed Vue中的计算属性是一种特殊的属性&#xff0c;它可以根据依赖的数据动态计算并返回结果。计算属性的值是通过getter函数计算得到的&#xff0c;当依赖的数据发生变化时&#xff0c;计算属性会自动重新计算并更新视图。计算属性具有缓存机制&#xff0c;只有当…

SSM的知识点考试系统java在线问答试卷管理jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 SSM的知识点考试系统 系统1权限&#xff1a;管理员 …

把大模型装进手机,分几步?

点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机&#xff0c;AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代&#xff0c;华为盘古大模型将会来助力鸿蒙生态。”8月4日&#xff0c;华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍&#xff0c…

【计算机网络】UDP服务器实现网络聊天室

前言 上一篇文章我们简单了解了一下什么是套接字编程&#xff0c;这篇文章我们利用UDP套接字来实现一个简单的网络聊天室。 编写UDP套接字服务器 成员变量 // 1. socket的id&#xff0c;相当于文件id int _sock; // 2. port uint16_t _port;// 3 一个线程负责收放消息&…

JUC并发、JVM相关

文章目录 JUC并发synchronized锁对象底层原理 synchronized锁升级reentrantlock公平锁和非公平锁可重入锁 / 递归锁 死锁死锁产生条件如何排查死锁?如果解决死锁&#xff1f; LockSupport与中断机制中断机制中断相关的三大API如何中断运行中的线程&#xff1f; LockSupportLoc…

【C++】C++11--- 线程库及详解lock_guard与unique_lock

目录 一、thread类的介绍二、线程函数参数三、 原子性操作库四、lock_guard与unique_lock4.1、mutex的种类4.2 lock_guard4.3 unique_lock 一、thread类的介绍 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如**windows和linux下各有自己…