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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP

😀前言

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

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


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

💞AOP-切入点表达式重用

🤔应用实例

● 切入点表达式重用

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

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

/**
     * 使用切面编程来替代原来的动态代理类,机制是一样的.
     * @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

🥰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

测试

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

💥注意事项和细节说明

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

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

😊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的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁

希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻

如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
XML Java 数据格式
Spring从入门到入土(xml配置文件的基础使用方式)
本文详细介绍了Spring框架中XML配置文件的使用方法,包括读取配置文件、创建带参数的构造对象、使用工厂方法和静态方法创建对象、对象生命周期管理以及单例和多例模式的测试。
97 7
Spring从入门到入土(xml配置文件的基础使用方式)
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
6月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
47 1
|
3月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
228 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
3月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
82 0
|
4月前
|
XML Java 数据格式
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
这篇文章详细介绍了Spring框架中IOC容器的Bean管理,特别是基于XML配置方式的实现。文章涵盖了Bean的定义、属性注入、使用set方法和构造函数注入,以及如何注入不同类型的属性,包括null值、特殊字符和外部bean。此外,还探讨了内部bean的概念及其与外部bean的比较,并提供了相应的示例代码和测试结果。
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
|
4月前
|
XML Java 数据格式
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
这篇文章是Spring5框架的实战教程,主题是IOC容器中Bean的集合属性注入,通过XML配置方式。文章详细讲解了如何在Spring中注入数组、List、Map和Set类型的集合属性,并提供了相应的XML配置示例和Java类定义。此外,还介绍了如何在集合中注入对象类型值,以及如何使用Spring的util命名空间来实现集合的复用。最后,通过测试代码和结果展示了注入效果。
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
|
4月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
4月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)