spring-aop的使用(注解 +配置类的方式)(多个增强类的优先级问题)

spring-aop

首先,准备一个接口以及其实现类

Calculator接口:src/main/java/com.atguigu.service/Calculator接口

package com.atguigu.service;

public interface Calculator {
    int add(int i, int j);

    int sub(int i, int j);

    int mul(int i, int j);

    int div(int i, int j);
}

Calculator接口的实现类:src/main/java/com.atguigu.service/impl/CalculatorImpl.java

package com.atguigu.service.impl;

import com.atguigu.service.Calculator;
import org.springframework.stereotype.Component;

@Component
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        int ret = i + j;
        return ret;
    }

    @Override
    public int sub(int i, int j) {
        int ret = i - j;
        return ret;
    }

    @Override
    public int mul(int i, int j) {
        int ret = i * j;
        return ret;
    }

    @Override
    public int div(int i, int j) {
        int ret = i / j;
        return ret;
    }
}

然后,写一个配置类JavaConfig.java

src/main/java/com.atguigu.config/JavaConfig.java

package com.atguigu.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.atguigu")
@EnableAspectJAutoProxy:开启aspectj的注解,等同于.xml配置文件的<aop:aspectj-autoproxy />
@EnableAspectJAutoProxy
public class JavaConfig {
}

再然后,写一个专门的切面表达式的类

src/main/java/com.atguigu.pointcut/MyPointCut.java

package com.atguigu.pointcut;

import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

这是专门存储切点表达式类
@Component
public class MyPointCut {
    @Pointcut("execution(* com.atguigu.service.impl.*.*(..))")
    public void pc(){}

    @Pointcut("execution(* com..impl.*.*(..))")
    public void myPc(){}
}

再再然后,专门的增强方法

src/main/java/com.atguigu.advice/MyAdvice.java

package com.atguigu.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Modifier;

在增强方法中,获取目标方法的信息
	* 1、获取目标方法的信息(方法名、参数、访问修饰符、所属的类信息...)
	       在方法的形参列表里,加(JoinPoint joinPoint)  import org.aspectj.lang.JoinPoint包下的
	       JoinPoint就包含了目标方法的信息
	
	* 2、获取返回的结果,在 @AfterReturning 时
	        在方法的形参列表里,加一个 returning = "ret",如下:
	        @AfterReturning(value = "execution(* com..impl.*.*(..))", returning = "ret")
	        public void afterReturning(JoinPoint joinPoint, Object ret){}

	* 3、获取异常一新,在 @AfterThrowing 时
	         在方法的形参列表里,加一个throwing = "throwable",如下:
	         @AfterThrowing(value = "execution(* com..impl.*.*(..))", throwing = "throwable")
	         public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {}


切点表达式:固定语法:execution(1 2 3.4.5(6))
	1:访问修饰符,public / privae
    2:方法的返回参数类型,String / int / void
    如果不考虑访问修饰符 和 返回值类型的话,这两位整合在一起,写成*
    这两位是一体的,如果不考虑就都不考虑,不能出现 * String 这种情况

    3:包的位置
        具体包:com.atguigu.service.impl
        单层模糊:com.atguigu.service.*
        多层模糊:com..impl
        记住,..不能开头哦
        例如:找出所有impl包:com..impl,不能写成..impl,能写成 *..impl

    4:类的名称
        具体:myCLass
        模糊:*
        部分模糊:*Impl,意思是类名以Impl结尾的

    5:方法名
        语法和 上面4类的名称一样

    6:形参列表
        没有参数:()
        有具体的参数:(String)(String,int)
        模糊参数:(..),意思是有没有参数都行,有多少个参数都行
        部分模糊:(String..),意思是String后面有没有无所谓
                 (..int),意思是,最后一个参数是int
                 (String..int),意思是,第一个参数是String,最后一个是int,中间的无所谓


说一下切点表达式的提取和复用
	方式1、在当前类中提取
         首先,定义一个public void xxx(){} 这样的空方法
         然后,用注解@Pointcut("execution(* com..impl.*.*(..))")
         最后,增强注解中,引用上面定义的xxx这个空方法即可

	方式2、创建一个专门存储切点表达式的Xxx类
         只不过使用的时候,要这样:Xxx类的权限定符.方法名()

如果,有多个增强类,优先使用哪一个?
	这就要用到:@Order(10),指定一个优先级的值,值越小,优先级越高,越高的前置先执行,后置后执行
	给增强类加上@Order(10)这个注解,就能控制这些增强类的优先级了


@Component
@Aspect
@Order(10)
public class MyAdvice {

	切点表达式的提取和复用 - 方式1、在当前类中提取
    @Pointcut("execution(* com..impl.*.*(..))")
    public void pc(){}

    @Before("execution(* com..impl.*.*(..))")
    public void before(JoinPoint joinPoint) {
        获取方法属于的类的信息
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        System.out.println("simpleName=" + simpleName);

        获取访问修饰符
        int modifiers = joinPoint.getSignature().getModifiers();
        String s = Modifier.toString(modifiers);

        获取方法名
        String name = joinPoint.getSignature().getName();
        System.out.println("name= " + name);

        获取目标方法的参数列表(就是获取目标方法的参数)
        Object[] args = joinPoint.getArgs();
    }

    @AfterReturning(value = "execution(* com..impl.*.*(..))", returning = "ret")
    public void afterReturning(JoinPoint joinPoint, Object ret) {
    }

    // @AfterThrowing(value = "execution(* com..impl.*.*(..))", throwing = "throwable")
    @AfterThrowing(value = "com.atguigu.pointcut.MyPointCut.myPc()", throwing = "throwable")
    public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {
    }

    // @After("execution(* com..impl.*.*(..))") 未使用 “切点表达式的提取和复用” 之前
    @After("pc()") // 使用 “切点表达式的提取和复用” 之后
    public void after(JoinPoint joinPoint) {
    }
}

最后,写一个测试类

src/text/java/com.atguigu.test/SpringAopTest.java

package com.atguigu.test;

import com.atguigu.config.JavaConfig;
import com.atguigu.service.Calculator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig(value = JavaConfig.class)
public class SpringAopTest {
    @Autowired
    private Calculator calculator;

    @Test
    public void test() {
        int add = calculator.add(1, 1);
        System.out.println("add= " + add);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[论文笔记]Root Mean Square Layer Normalization

引言 今天带来论文Root Mean Square Layer Normalization的笔记&#xff0c;论文题目是均方根层归一化。 本篇工作提出了RMSNorm&#xff0c;认为可以省略重新居中步骤。 简介 层归一化对Transformer等模型非常重要&#xff0c;它可以帮助稳定训练并提升模型收敛性&#xf…

生成对抗网络GAN的扩展应用理解

注&#xff1a;本文仅个人学习理解&#xff0c;如需详细内容请看原论文&#xff01; 一、cycleGAN 1.整体架构&#xff1a; 将图片A通过生成器生成图片B&#xff0c;然后通过判别器判别图片B的真假&#xff1b;并且图片B通过另一个生成器生成A‘&#xff0c;让A和A’近似。 2…

Python这十大特征,堪称“圆满”!

当你犹豫是否要开始 Python 学习之前&#xff0c;可以先详尽了解一下这门编程语言。 软件开发者 Guido Van Rossum 于 1991 年创建了 Python&#xff0c;旨在使程序员的工作更加简单。Python 是目前全球比较流行且产业急需的程序设计语言&#xff0c;也是一门跨平台、开源、免…

2024-8.python作用域+函数其他

变量的作用域 讲到了函数就必须介绍变量的作用域相关。 作用域指的是变量的有效范围。变量并不是在哪个位置都可以访问的&#xff0c;访问权限取决于这个变量是在哪里赋值的&#xff0c;也就是在哪个作用域内赋的值。变量在哪个作用域内赋值&#xff0c;则表示该变量的作用域就…

POST 为什么会发送两次请求?

本文目录 同源策略 什么是同源策略 CORS 简单请求 预检请求 附带身份凭证的请求与通配符 完整的请求流程图 总结 前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;因为在前端开发的日常开发中我们总是会与post请求…

【数据结构】-- 栈和队列

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

Mybatis-plus中的分页操作

Mybatis-plus中的分页操作 1.导入Mybatis-plus依赖2.创建mybatis配置类3.参数 1.导入Mybatis-plus依赖 因为是一个springboot项目&#xff0c;其中的pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns&q…

ping命令的使用

一、实验环境 同实验案例分析ARP解析过程环境。 二、需求描述 熟悉 ping 命令的用法并熱悉 ping 命令的各种参数 三、推荐步骤 分别 ping 一个存在的和不存在的IP地址&#xff0c;观察返回的信息分别测试 ping 命令的相关参数。 四、实验步骤 1.ping 一个存在的和不存在…

数据加密、文档加密为什么都选择安企神软件

数据加密、文档加密为什么都选择安企神软件 免费试用安企神 在数据加密和文件加密领域&#xff0c;有众多优秀的软件&#xff0c;他们功能各异、价格不同、效果也大相径庭&#xff0c;经过对比使用、用户口碑和技术网站评判&#xff0c;安企神在各方面都稳坐第一把交易。其原…

ECA-Net:深度卷积神经网络中的高效通道注意力机制【原理讲解及代码!!!】

ECA-Net&#xff1a;深度卷积神经网络中的高效通道注意力机制 在深度学习领域&#xff0c;特别是在深度卷积神经网络&#xff08;DCNN&#xff09;中&#xff0c;注意力机制已经成为提升模型性能的关键技术之一。其中&#xff0c;ECA模块&#xff08;Efficient Channel Attent…

Nginx常用配置,开箱即用

经常遇到Nginx安装和配置的问题。这里笔者将常用配置统统写在下面&#xff0c;方便咱们日常使用。这里本着开箱即用的原则&#xff0c;所以大多数时候不会解释为什么要这样去配置&#xff0c;也不涉及Nginx的安装步骤。下面的所有配置&#xff0c;都可以直接复制后粘贴使用&…

虚幻引擎源码版安装下载,点击GenerateProjectFiles.bat报错 error NU1101NuGet包问题解决参考方案

开发环境配置与源码安装使用 安装VS2022 按照官方文档安装需要的vs配置 虚幻引擎源代码下载 Epic里面下载的引擎与源代码引擎区别&#xff1a;Epic里面下载的引擎是已经编译过的它的源代码访问权限不完整&#xff0c;源代码版本提供比较完整引擎代码&#xff0c;并且可以修…

顺序表(增删减改)+通讯录项目(数据结构)+顺序表专用题型

什么是顺序表 顺序表和数组的区别 顺序表本质就是数组 结构体初阶进阶 系统化的学习-CSDN博客 简单解释一下&#xff0c;就像大家去吃饭&#xff0c;然后左边是苍蝇馆子&#xff0c;右边是修饰过的苍蝇馆子&#xff0c;但是那个好看的苍蝇馆子一看&#xff0c;这不行啊&a…

SAP NWDI(二)服务开启(SLD,CM,CMS)

一、启用System Landscape Directory 二、启用 NWDI using CMS

反射

目录 01、Java反射机制概述1.1、使用反射&#xff0c;实现同上的操作、调用私有属性 02、理解Class类并获取Class实例2.1、Class类的理解2.2、获取Class实例的4种方式2.3、Class实例对应的结构的说明 03、ClassLoader的理解3.1、ClassLoader的理解3.2、使用ClassLoader加载配置…

C语言【数组】

一、数组基本语法 1. 什么是数组 数组是c语言的一种数据结构&#xff0c;用于存储一组具有相同数据类型的数据&#xff1b; 数组中每个元素可以通过下标进行访问&#xff0c;索引从0开始&#xff0c;最大值为数组长度-1。 2. 数组的使用 类型 数组名[元素个数]; int arr[5]…

xftp、xshell连不上虚拟机解决方法

一、检查连接虚拟机ip看是否正确 查看虚拟机系统 IP ifconfig 二、检查虚拟机防火墙是否关闭 查看防火墙状态(ubuntu) sudo ufw status 关闭防火墙 sudo ufw disable 查看防火墙状态(centos) systemctl status firewalld.service 关闭防火墙 systemctl stop firewalld.se…

HarmonyOS Next 悬浮窗拖拽和吸附动画

介绍 本示例使用position绝对定位实现应用内悬浮窗&#xff0c;并且通过animateTo结合curves动画曲线实现悬浮窗拖拽跟手和松手吸附边缘的弹性动画效果。 效果图预览 使用说明 按住悬浮窗可以拖拽&#xff0c;松开后悬浮窗自动靠左或靠右&#xff0c;如果悬浮窗超出内容区上…

线圈、寄存器、存储区代号、功能码 案例说明

线圈和寄存器 表示数据类型 线圈&#xff1a;表示Boolean数据类型 寄存器&#xff1a;表示非Boolean数据类型&#xff0c;用来暂时存放参与运算的数据和运算结果&#xff0c;具有接收数据、存放数据和输出数据的功能。 ModbusRTU 读输出线圈 存储区代号 0区 功能码 0x01 读输入…

冯喜运:4.17晚间黄金原油操作建议

【黄金消息面解析 】&#xff1a;周三(4月17日)欧洲时段&#xff0c;现货黄金短线持续反弹&#xff0c;当前金价位于2394美元/盎司附近&#xff0c;已从日内低点2372美元/盎司附近回升。金价在触及纪录高位2432美元/盎司后形成了对称三角形。金价下一个潜在障碍为历史高位2432美…
最新文章