SpringBoot、Java AOP实现方式

SpringBoot、Java AOP实现方式

搭建项目环境

我这里直接使用Maven创建项目之后再pom.xml中导入包

在这里插入图片描述

Spring版本

如果你的版本有最新的,最简单的办法就是,将版本都换成统一的,因为发布时候都是每个版本统一发布的,如果出现不兼容的情况,最简单有效的办法就是:将版本换成统一的

导入的有:

  1. spring-context
  2. spring-aop
  3. spring-aspects
  4. spring-test
  5. junit
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>6.1.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.1.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version></dependency>
</dependencies>

新建Java文件Calculator接口

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);
}

在这里插入图片描述

新建实现类CalculatorImpl

记得再上面加上@Component否则SpringBoot扫描不到!!!

package org.example.calc.impl;import org.example.calc.Calculator;
import org.springframework.stereotype.Component;@Component
public class CalculatorImpl implements Calculator {@Overridepublic int add(int i, int j) {return 0;}@Overridepublic int sub(int i, int j) {return 0;}@Overridepublic int mul(int i, int j) {return 0;}@Overridepublic int div(int i, int j) {return 0;}
}

在这里插入图片描述

新建LogAspect切面

待会就在这个文件中写入切面方法,其中有这几个方法

环绕通知:上面四个都会包含在内!!!

Before 前置通知
After 后置通知
AfterReturning 返回通知
AfterThrowing 异常通知
Around 环绕通知

新建文件是这样的

package org.example.calc;import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LogAspect {}

一定要在这个文件夹下新建否则不会生效

在这里插入图片描述

新建xml文件

文件内容是这样的还没有写入内容,这个文件名随便取一个,我就叫bean.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"></beans>

在这里插入图片描述

创建切面

xml内容

在你resource下创建的xml文件中添加下面代码,其中<context:component-scan base-package="指向的是目录下Calculator接口"/>

这一步至关重要,否则后面找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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="org.example.calc"/><aop:aspectj-autoproxy/>
</beans>

在这里插入图片描述

LogAspect实现

Before简单的实现:前置操作

第一步先不搞复杂的先试试效果

在文件中写入

其中@Before(execution(表达式))

@Aspect
@Component
public class LogAspect {@Before(value = "execution(public int org.example.calc.Calculator.*(..))")public void beforeMethod() {System.out.println("前置操作");}
}

在这里插入图片描述

之后在测试文件中写下测试代码

import org.example.calc.Calculator;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AopTest {@Testpublic void test() {ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");Calculator contextBean = context.getBean(Calculator.class);contextBean.add(1, 2);}
}

在这里插入图片描述

运行成功!!!

Before 带参数前置操作

要在方法中加入JoinPoint

@Aspect
@Component
public class LogAspect {@Before(value = "execution(public int org.example.calc.Calculator.*(..))")public void beforeMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();// 获取连接点的签名信息Object[] args = joinPoint.getArgs();// 实参信息System.out.println("前置通知-->name" + name + "args" + Arrays.toString(args));}
}

在这里插入图片描述

运行成功

复用value中表达式

因为有时一个项目中会有很多相同的表达式这是需要复用,可以做以下操作

只需要在这个文件中加入这个方法即可,方法名字可以随便取

需要注意的是这个里面不要填写value!!!

调用时要加括号不要只写方法名!!!

如:@After(value = "pointcut()")

@Pointcut("execution(public int org.example.calc.Calculator.*(..))")
public void pointcut() {
}
After 后置通知
package org.example.calc;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import java.util.Arrays;@Aspect
@Component
public class LogAspect {/*** 前置通知** @param joinPoint JoinPoint*/@Before(value = "execution(public int org.example.calc.Calculator.*(..))")public void beforeMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();// 获取连接点的签名信息Object[] args = joinPoint.getArgs();// 实参信息System.out.println("前置通知-->name" + name + "args" + Arrays.toString(args));}/*** 后置通知** @param joinPoint JoinPoint*/@After(value = "pointcut()")public void afterMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->后置通知,方法名称:" + name + ",参数:" + Arrays.toString(args));}@Pointcut("execution(public int org.example.calc.Calculator.*(..))")public void pointcut() {}
}
AfterReturning 返回通知&引入外部表达式

如果这个表达式是外部的如何引入?

直接在前面加上方法名即可

@AfterReturning(value = "org.example.calc.LogAspect.pointcut()")

返回通知写法

/*** 返回通知** @param joinPoint JoinPoint*/
@AfterReturning(value = "org.example.calc.LogAspect.pointcut()")
public void afterReturningMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->返回通知,方法名称:" + name + ",参数:" + Arrays.toString(args));
}
AfterThrowing 异常通知
/*** 异常通知* @param joinPoint JoinPoint*/
@AfterThrowing(value = "pointcut()")
public void afterThrowingMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->异常通知,方法名称:" + name + ",参数:" + Arrays.toString(args));
}
Around 环绕通知

注意的是这次在方法中使用的是ProceedingJoinPoint!!!

@Around(value = "pointcut()")
public Object aroundMethod(ProceedingJoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();Object result = null;try {System.out.println("环绕通知-->目标对象方法执行之前");result = joinPoint.proceed();System.out.println("环绕通知-->目标对象方法返回值之后} catch (Throwable e) {e.printStackTrace();System.out.println("环绕通知-->目标对象方法出现异常时");}finally {System.out.println("环绕通知-->目标对象方法执行完毕");}return result;
}

测试通过

在这里插入图片描述

在xml中配置切面

删除注解

因为在配置文件的xml中写入,所以要将5个注解全部删除,之后创建新的xml文件,你用旧的也可以。

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;import java.util.Arrays;@Aspect
@Component
public class LogAspect {public void beforeMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();// 获取连接点的签名信息Object[] args = joinPoint.getArgs();// 实参信息System.out.println("前置通知-->name" + name + "args" + Arrays.toString(args));}public void afterMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->后置通知,方法名称:" + name + ",参数:" + Arrays.toString(args));}public void afterReturningMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->返回通知,方法名称:" + name + ",参数:" + Arrays.toString(args));}public void afterThrowingMethod(JoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Logger-->异常通知,方法名称:" + name + ",参数:" + Arrays.toString(args));}public Object aroundMethod(ProceedingJoinPoint joinPoint) {String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();Object result = null;try {System.out.println("环绕通知-->目标对象方法执行之前");result = joinPoint.proceed();System.out.println("环绕通知-->目标对象方法返回值之后");} catch (Throwable e) {e.printStackTrace();System.out.println("环绕通知-->目标对象方法出现异常时");}finally {System.out.println("环绕通知-->目标对象方法执行完毕");}return result;}
}

在这里插入图片描述

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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="org.example.calc"/><aop:config><!-- 配置切面类 --><aop:aspect ref="logAspect"><!-- 表达式 --><aop:pointcut id="pointcut" expression="execution(public int org.example.calc.Calculator.*(..))"/><!-- 前置操作 --><aop:before method="beforeMethod" pointcut-ref="pointcut"/><!-- 后置操作 --><aop:after method="afterMethod" pointcut-ref="pointcut"/><!-- 返回操作 --><aop:after-returning method="afterReturningMethod" returning="result" pointcut-ref="pointcut"/><!-- 异常通知 --><aop:after-throwing method="afterThrowingMethod" throwing="ex" pointcut-ref="pointcut"/><aop:around method="aroundMethod" pointcut-ref="pointcut"/></aop:aspect></aop:config>
</beans>

运行成功

在这里插入图片描述

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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="org.example.calc"/><aop:config><!-- 配置切面类 --><aop:aspect ref="你的类开头字母小写"><!-- 表达式 --><aop:pointcut id="这个名字随便取" expression="表达式的值"/><!-- 前置操作 --><aop:before method="前置操作方法,正常会有提示的" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 后置操作 --><aop:after method="后置操作方法" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 返回操作 --><aop:after-returning method="返回操作方法" returning="返回值,你的返回值是什么变量就填什么" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 异常通知 --><aop:after-throwing method="异常通知方法" throwing="抛出异常命名,见下面图片" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 环绕通知 --><aop:around method="aroundMethod" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/></aop:aspect></aop:config>
</beans>

抛出异常名根据这个来的

不要加括号!!!"/>

        <!-- 返回操作 --><aop:after-returning method="返回操作方法" returning="返回值,你的返回值是什么变量就填什么" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 异常通知 --><aop:after-throwing method="异常通知方法" throwing="抛出异常命名,见下面图片" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/><!-- 环绕通知 --><aop:around method="aroundMethod" pointcut-ref="注意这里是pointcut-ref,是上面填写表达式的值,不要加括号!!!"/></aop:aspect>
</aop:config>
```

抛出异常名根据这个来的

在这里插入图片描述

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

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

相关文章

大模型讲座

盘古NLP大模型典型场景 千亿大模型训练难点和解决方案 训练状态不稳定&#xff08;经常训练中断等&#xff09; 解决1&#xff1a;对loss和梯度等多维状态实时监测。对数据、学习率、参数精度、模型梯度进行针对性调整和断点恢复。 调整学习率的代码如下。调整参数、梯度类似…

kali安装HTTrack报错Unable to locate package httrack

kali安装后&#xff0c;直接安装Httrack导致报错 Unable to locate package httrack &#xff08;这里因为解决了&#xff0c;无法重现&#xff0c;则使用错误的包httrackttttt&#xff09; 原因&#xff1a;安装kali后第一次使用系统&#xff0c;则应该运行update命令 sudo …

基于ssm省出口基地公共信息服务平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本n省出口基地公共信息服务平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞…

算法训练营Day19

#Java #二叉树 #双指针 开源学习资料 Feeling and experiences&#xff1a; 二叉搜索树的最小绝对差&#xff1a;力扣题目链接 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的…

eNSP小实验--实现全网互通

目录 一、建立以下拓扑图&#xff0c;并实现全网互通 二、分析 1、接入层交换机SW4、SW5划分vlan 2、汇聚层交换机SW2,SW3配置ip作为vlan网关&#xff0c;与SW1直连 3、核心交换机SW1配置ip 与汇聚层交换机和R1直连 4、SW1,SW2,SW3,R1配置静态路由&#xff0c;使得vlan10,…

算法学习——回溯算法

回溯算法 理论基础回溯法的效率回溯法解决的问题回溯法模板 组合思路回溯法三部曲 代码 组合&#xff08;优化&#xff09;组合总和III思路代码 电话号码的字母组合思路回溯法来解决n个for循环的问题回溯三部曲代码 组合总和思路代码 组合总和II思路代码 理论基础 什么是回溯法…

教师职业规划

教师是一份充满责任和使命感的职业&#xff0c;也是一个具有广泛影响力的职业。作为一名教师&#xff0c;不仅要传授知识&#xff0c;更要培养学生的品德和能力&#xff0c;为他们的未来发展奠定基础。因此&#xff0c;进行职业规划对于教师来说是非常重要的。 首先&#xff0…

VUE篇之可拖动裁剪框

涉及知识点&#xff1a; offsetLeft, offsetTop, offsetWidth, offsetHeight&#xff1b;offsetX, offsetY&#xff1b;clientX&#xff0c;clientY css:clip-path 学习直通车&#xff1a;HTMLElement.offsetLeft - Web API 接口参考 | MDN MouseEvent.offsetX - Web API 接…

利用原始套接字解决mac地址错误问题【南瑞SysKeeper-2000】

一&#xff1a;案例描述 一键可视顺控图像智能项目在网络部署过程中&#xff0c;对网络限制隔离安全性要求很高&#xff0c;用到正向隔离装置&#xff08;南瑞SysKeeper-2000型号&#xff09;。 图一 正向装置示意图 现场发现问题&#xff1a;直连网线情况下&#xff0c;我方…

德人合科技 | 公司电脑文件加密系统

公司电脑文件加密系统是一种可以对电脑文件进行加密的保护机制。它使用驱动层透明加密技术&#xff0c;能够在用户无感知的情况下对文件进行加密&#xff0c;从源头上保障数据安全和使用安全。 PC端访问地址&#xff1a; www.drhchina.com 此类系统主要有以下几个特点和功能&a…

Web前端-JavaScript(js循环)

1.循环 1.1 for循环 语法结构 for(初始化变量; 条件表达式; 操作表达式 ){//循环体 }名称作用初始化变量通常被用于初始化一个计数器&#xff0c;该表达式可以使用 var 关键字声明新的变量&#xff0c;这个变量帮我们来记录次数。条件表达式用于确定每一次循环是否能被执行。…

Git账户密码http方式的配置

Git账户密码http方式的配置 入门 git在提交时每次都需要输入密码和账号信息&#xff0c;可以将账号和密码进行持久化存储&#xff0c; 当git push的时候输入一次用户名和密码就会被记录&#xff0c; 不需要每次输入&#xff0c;提高效率&#xff0c;进行一下配置&#xff1…

深入学习《大学计算机》系列之第1章 1.4节——从二进制起源窥见的奥秘

一.欢迎来到我的酒馆 第1章 1.4节&#xff0c;从二进制起源窥见的奥秘。 目录 一.欢迎来到我的酒馆二.二进制的起源1.关于莱布尼茨2.莱布尼茨和牛顿的恩怨情仇 二.二进制的起源 本节内容属于知识拓展&#xff0c;通过讲解几个小故事&#xff0c;向大家介绍二进制的起源。 1.关…

基于低代码的文档管理系统:实现高效协作与控制

在企业和组织中&#xff0c;文档管理是一项至关重要的任务。文档包括各种类型的信息&#xff0c;如合同、报告、会议记录、产品规格等&#xff0c;它们都需要被妥善保管并确保随时可供查阅。 传统的文档管理方法往往效率低下&#xff0c;且容易出错。随着技术的发展&#xff0…

亚信安慧AntDB数据库引领大数据新纪元,星河案例彰显卓越表现

亚信科技及其附属公司亚信安慧在第六届大数据“星河”案例评选中&#xff0c;凭借其卓越的数据库技术实力&#xff0c;再次站在了行业的聚光灯下。这次的显著成果不仅是对亚信科技技术能力的肯定&#xff0c;更是对其在数据库领域持续创新和领先地位的认可。 图&#xff1a;亚信…

3D小球跑酷

目录 一、前言 二、开发环境 三、场景搭建 1. 创建项目 2. 创建场景内物体 2.1 创建跑道 2.2 创建玩家 2.3 创建障碍物 2.4 改变跑道和障碍物的颜色 2.4.1 创建材质 2.4.2 给跑道和障碍物更换材质 四、功能脚本实现 1. 创建玩家脚本 2. 相机跟随 3. 胜负的判定 3…

单光子如何“玩转”单原子?| 量子简史

在量子力学诞生约100年后的今天&#xff0c;物理学家仍在不断了解光与物质之间的相互作用。 上世纪初&#xff0c;量子力学发展的驱动力之一是人们需要了解为什么原子只能发出特定波长的光。不久之后&#xff0c;量子力学被应用于分子&#xff0c;然后是固体。从另一个方向来看…

Springboot数据加密篇

一、密码加密 1.1Hash算法(MD5/SHA-512等) 哈希算法&#xff0c;又称摘要算法&#xff08;Digest&#xff09;&#xff0c;是一种将任意长度的输入通过散列函数变换成固定长度的输出的单向密码体制。这种映射的规则就是哈希算法&#xff0c;而通过原始数据映射之后得到的二进制…

STM32——串口通信应用篇

一、引言 STM32微控制器是一款功能强大的嵌入式系统芯片&#xff0c;广泛应用于各种领域。其中&#xff0c;串口通信是其重要功能之一&#xff0c;可用于与外部设备进行数据交换和控制。本文将介绍STM32串口通信的基本原理、应用场景以及实现方法。 二、STM32串口通信基本原理 …

三维模型轻量化工具

老子云三维模型服务平台&#xff1a;常规模型轻量化通过底层算法快速有效的对常规模型进行轻量化处理&#xff0c;目前包含两种处理模式&#xff1a;减面模式、合并模式。 减面模式&#xff1a;保留原始模型信息&#xff0c;仅使模型网格更轻量。合并模式&#xff1a;合并模型材…