Spring-AOP入门案例
文章目录
- Spring-AOP入门案例
- 简单需求:在接口执行前输出当前系统时间
- Demo原始未添加aop前
- 1 项目包结构
- 2 创建相关文件
- 2.1 pom.xml
- 2.2 创建BookDao类
- 2.3 创建BookDaoImpl实现类
- 2.4 创建MySpringConfig配置类
- 2.5 创建DemoAop主启动类
- 打印结果
- Demo案例添加aop
- 1 pom.xml引入相关的配置包
- 2 把共性的方法抽取出来,定义一个新的类(通知类,切入位置绑定相关的业务方法)
- 3 配置类添加@EnableAspectJAutoProxy
- 4 启动主启动类,未修改update原有方法,已切入共性方法
- 项目中异常问题
- @Repository注解报红,需要引入Spring依赖,或者直接引入springboot依赖
- 方案解决一:
- 方案解决二:
- AOP注解综合概念使用
- Run方法获取class类,反射class类
- 1 使用注解
- 2 读取配置文件:
Spring-AOP入门案例
概念:
AOP为Aspect Oriented Programming的缩写,又被称为面向切面编程, 对接口进行动态代理,需要引入切面框架Aspect,用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率;
不去动原来的代码,而是基于原来代码产生代理对象,通过代理的方法去包装原来的方法,就完成了对以前方法的增强。换句话说,AOP的底层原理就是动态代理的实现。应用场景:一般应用在需要多个业务流程中都需要相同或类似的业务处理,且与核心业务无关,则特别适合用AOP技术来解决; 包括权限,日志和持久化等等。
通知(Advice)
前置增强、后置增强、环绕增强、异常抛出增强、引介增强等类型。
(1)前置增强:org.springframework.aop.BeforeAdvice代表前置增强,spring只支持方法级的增强,目前可用MethodBeforeAdvice。
(2)后置增强:org.springframework.aop.AfterReturningAdvice代表后置增强,在目标方法执行后实施增强。
(3)环绕增强:org.aopalliance.intercept.MethodInterceptor代表环绕增强,在目标方法执行前后实施增强。
(4)异常抛出增强:org.springframework.aop.ThrowsAdvice,在目标方法执行抛出异常后实施增强。方法名必须为afterThrowing,
如参前三个可选,最后一个是Throwable或其子类。
(5)引介增强:org.springframework.aop.IntroductionInterceptor,表示目标类添加一些新的方法和属性,连接点是类级别,而不是方法级别。
如:
在方法执行之前验证用户是否有效。 在方法执行之后,打印方法的执行耗时。 在方法抛出异常后,记录异常信息发送到mq。
切入点(Pointcut )
用来指定需要将通知使用到哪些方法上; 比如需要用在哪些类的哪些方法上,切入点就是做这个配置的。
也可以把这个表达式理解为一个查询条件,系统会根据这个查询条件查询到我们要进行增强的代码位置。
切面(Aspect)
通知(Advice)和切入点(Pointcut)的组合。切面来定义在哪些地方(Pointcut)执行什么操作(Advice)。
简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,
便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;
那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。
而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
目标对象(target)
目标对象指将要被增强的对象,即包含主业务逻辑的类对象;我们也称之为委托类。
代理对象(Proxy)
AOP中会通过代理的方式,对目标对象生成一个代理对象,代理对象中会加入需要增强功能,通过代理对象来间接的方式目标对象,起到增强目标对象的效果。
顾问(Advisor)
Advisor 其实它就是 Pointcut 与 Advice 的组合,Advice 是要增强的逻辑,而增强的逻辑要在什么地方执行是通过Pointcut来指定的,所以 Advice 必需与 Pointcut 组合在一起,这就诞生了 Advisor 这个类,spring Aop中提供了一个Advisor接口将Pointcut 与 Advice 的组合起来。Advisor有好几个称呼:顾问、通知器。其中这4个:连接点(JoinPoint)、通知(advise)、切入点(pointcut)、顾问(advisor),在spring中都定义了接口和类来表示这些对象。
连接点(JoinPoint)
就是SpringAOP通过告诉它的切入点的位置找的的具体的要增强的代码的位置,这个代码位置就是连接点。连接点由两个信息确定: 方法(表示程序执行点,即在哪个目标方法) 相对点(表示方位,即目标方法的什么位置,比如调用前,后等)简单来说,连接点就是被拦截到的程序执行点,因为Spring只支持方法类型的连接点,所以在Spring中连接点就是被拦截到的方法。
简单需求:在接口执行前输出当前系统时间
开发模式:可以XML 或者 注解进行实现
思路分析:
- 1 导入坐标(pom.xml)
- 2 制作连接方法(Dao与实现类)
- 3 制作共性功能(通知类与通知)
- 4 定义切入点
- 5 绑定切入点与通知关系(切面)
Demo原始未添加aop前
1 项目包结构
2 创建相关文件
2.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>test-maven-aop</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.2</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>
2.2 创建BookDao类
package com.test.dao;public interface BookDao {public void save();public void update();
}
2.3 创建BookDaoImpl实现类
package com.test.dao.impl;import com.test.dao.BookDao;
import org.springframework.stereotype.Repository;@Repository
public class BookDaoImpl implements BookDao{public void save() {System.out.println(System.currentTimeMillis());System.out.println("book dao save ...");}public void update() {System.out.println("book dao update ...");}
}
2.4 创建MySpringConfig配置类
package com.test.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("com.test")
public class MySpringConfig {}
2.5 创建DemoAop主启动类
package com.test;import com.test.config.MySpringConfig;
import com.test.dao.BookDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DemoAop {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MySpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.save(); // 当前的系统时间打印了// bookDao.update(); 需求执行这个方法需要执行打印系统时间,不能修改update的原始方法/*** AnnotationConfigApplicationContext是spring中利用注解配置的方式构建spring上下文的类。* 对于具体使用参考https://www.cnblogs.com/javasl/p/11783484.html**/}}
打印结果
Demo案例添加aop
1 pom.xml引入相关的配置包
<dependencies><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency></dependencies>
查看包依赖可以看到context包导入后,aop就会导入了
2 把共性的方法抽取出来,定义一个新的类(通知类,切入位置绑定相关的业务方法)
package com.test.aop;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Component
@Aspect
public class MyAdvice {// 定义切入点// 返回是void类型,具体哪个方法@Pointcut("execution(void com.test.dao.BookDao.update())")private void pt(){} // 空方法@Before("pt()")public void method() { // 共性功能System.out.println(System.currentTimeMillis());}/*第1定义共性方法,切入的方法method(),还没有@Before注解,第3步加入的第2步 定义切入点Pointcut,当执行到pt(),执行切入点方法"execution(void com.test.dao.BookDao.update())"第3步 绑入切入点的之间关系 --在com.test.dao.BookDao.update()方法什么时候执行method()方法,使用@Before(“”)第4步 需要受到spring的管理,@component。定义bean,加@Aspect告诉spring,当aop处理,生效第5步 配置类中package com.test.config。MySpringConfig 通知这个类,我是注解开发的@EnableAspectJAutoProxy,这个启动了@Aspect,识别相关的Pointcut等注解*/
}
3 配置类添加@EnableAspectJAutoProxy
package com.test.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan("com.test")
@EnableAspectJAutoProxy
public class MySpringConfig {}
4 启动主启动类,未修改update原有方法,已切入共性方法
项目中异常问题
@Repository是属于Spring的注解。它用来标注访问层的类(Dao层),它表示一个仓库,主要用于封装对于数据库的访问。其实现方式与@Component注解相同,只是为了明确类的作用而设立。
即@Repository是@Component注解的一个派生品,与@Service和@Controller都可以理解为@Component注解的扩展。他们的作用都是在类上实例化bean,并把当前类对象的实现类交给spring容器进行管理。
Repository注解修饰哪个类表明这个类具有对数据库CRUD的功能,用在持久层的接口上。
@Repository注解报红,需要引入Spring依赖,或者直接引入springboot依赖
方案解决一:
<properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><spring.version>5.3.15</spring.version>
</properties>
<!-- Spring -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version>
</dependency>
方案解决二:
添加Web场景依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
AOP注解综合概念使用
/** * 日志切面类 */
@Aspect //定义切面类
public class LogAnnotationAspect { @SuppressWarnings("unused") //定义切入点,提供一个方法,这个方法的名字就是改切入点的id @Pointcut("execution(* com.abc.service.*.*(..))") private void allMethod(){} //针对指定的切入点表达式选择的切入点应用前置通知 @Before("execution(* com.abc.service.*.*(..))") public void before(JoinPoint call) { String className = call.getTarget().getClass().getName(); String methodName = call.getSignature().getName(); System.out.println("【注解-前置通知】:" + className + "类的" + methodName + "方法开始了"); } //访问命名切入点来应用后置通知 @AfterReturning("allMethod()") public void afterReturn() { System.out.println("【注解-后置通知】:方法正常结束了"); } //应用最终通知 @After("allMethod()") public void after(){ System.out.println("【注解-最终通知】:不管方法有没有正常执行完成," + "一定会返回的"); } //应用异常抛出后通知 @AfterThrowing("allMethod()") public void afterThrowing() { System.out.println("【注解-异常抛出后通知】:方法执行时出异常了"); } //应用周围通知 //@Around("allMethod()") public Object doAround(ProceedingJoinPoint call) throws Throwable{ Object result = null; //相当于前置通知 this.before(call);try { result = call.proceed();//相当于后置通知 this.afterReturn(); } catch (Throwable e) { //相当于异常抛出后通知 this.afterThrowing(); throw e; }finally{ //相当于最终通知 this.after(); } return result; }
}
Run方法获取class类,反射class类
1 使用注解
AnnotationConfigApplicationContext是spring中利用注解配置的方式构建spring上下文的类。
第一种方式:构造函数传入一个或者多个类。可以是注解类,也可以是普通类,传入的类都会纳入到spring容器中。如下:
第二种方式:构造函数传入一个包名,该包下的类都会创建bean,并且纳入spring容器中
App.java,User.class没有加注解,不会创建bean
第三种方式:构造函数传入一个加了@ComponentScan注解的类,该注解指明了扫描的包和排除掉的类参考文章:https://www.cnblogs.com/javasl/p/11783484.html
2 读取配置文件:
使用XML创建bean参考文章:`https://zhuanlan.zhihu.com/p/572380275`
相关文章:

Spring-AOP入门案例
文章目录 Spring-AOP入门案例概念:通知(Advice)切入点(Pointcut )切面(Aspect) 目标对象(target)代理对象(Proxy)顾问(Advisor)连接点(JoinPoint) 简单需求:在接口执行前输出当前系统时间Demo原始未添加aop前1 项目包结构2 创建相…...

中仕教育:国考调剂和补录的区别是什么?
国考笔试成绩和进面名单公布之后,考生们就需要关注调剂和补录了,针对二者之间的区别很多考生不太了解,本文为大家解答一下关于国考调剂和补录的区别。 1.补录 补录是在公式环节之后进行的,主要原因是经过面试、体检和考察&#…...

ESP32-TCP服务端(Arduino)
将ESP32设置为TCP服务器 介绍 TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的(一个客户端对应一个服务端)、可靠的传输层协议。在TCP的工作原理中,它会将消息或文件分解为更小的片段&a…...

HCIA-HarmonyOS设备开发认证-序
序 最近涉及到HarmonyOS鸿蒙系统设备开发,在网络上已经有很多相关资料,视频教程,我也移植了公司的一个stm32G474板卡,运行LiteOS-m L0系统。 一面看资料一面移植,遇到不少坑,当看到运行的LOGO时࿰…...

Med-YOLO:3D + 医学影像 + 检测框架
Med-YOLO:3D 医学影像 检测框架 提出背景设计思路网络设计训练设计讨论分析 魔改代码:加强小目标检测总结 提出背景 论文链接:https://arxiv.org/abs/2312.07729 代码链接:https://github.com/JDSobek/MedYOLO 提出背景&…...

Docker部署Golang服务
不管是开发还是生产环境,通过 docker 方式部署服务都是一种不错的选择,能够解决不同开发环境一致性的问题。 本文以项目:https://github.com/johncxf/go-api 为例。 Dockerfile 构建 Go 运用环境 在项目根目录下添加 Dockerfile 文件&…...

C#,字符串匹配(模式搜索)Sunday算法的源代码
Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法。 核心思想:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配&…...

makefile 编译动态链接库使用(.so库文件)
makefile 编译动态链接库使用(.so库文件) 动态链接库:不会把代码编译到二进制文件中,而是在运行时才去加载, 好处是程序可以和库文件分离,可以分别发版,然后库文件可以被多处共享 动态链接库 动态&#…...

Hive 数仓及数仓设计方案
数仓(Data Warehouse) 数据仓库存在的意义在于对企业的所有数据进行汇总,为企业各个部门提供一个统一、规范的出口。做数仓就是做方案,是用数据治理企业的方案。 数据仓库的特点 面向主题集成 公司中不同的部门都会去数据仓库中拿数据,把独…...

Ubuntu使用docker-compose安装redis
ubuntu环境搭建专栏🔗点击跳转 Ubuntu系统环境搭建(十三)——使用docker-compose安装redis 文章目录 Ubuntu系统环境搭建(十三)——使用docker-compose安装redis1.搭建文件夹2.docker-compose.yaml配置文件3.redis.co…...

大数据安全 | 期末复习(上)| 补档
文章目录 📚概述⭐️🐇大数据的定义、来源、特点🐇大数据安全的含义🐇大数据安全威胁🐇保障大数据安全🐇采集、存储、挖掘环节的安全技术🐇大数据用于安全🐇隐私的定义、属性、分类、…...

Kylin 安装novnc 远程访问
noVNC可以使用浏览器直接访问服务器,而不需要使用VNC客户端。 1.初始环境 关闭防火墙或允许IP访问本机 2.安装依赖 dnf install -y tigervnc-server git 3.git下载novnc git clone https://github.com/novnc/noVNC.git git clone https://gitee.com/yangyizhao…...

神经网络算法与逻辑回归:优势与差异
神经网络算法和逻辑回归都是预测模型中的重要工具,但它们在处理复杂和非线性问题时表现出不同的性能。本文将深入探讨神经网络算法相对于逻辑回归的优势,以及它们在不同场景下的适用性。 一、引言 神经网络算法和逻辑回归都是预测模型中的重要工具&…...

【蓝桥杯冲冲冲】动态规划初步[USACO2006 OPEN] 县集市
蓝桥杯备赛 | 洛谷做题打卡day13 文章目录 蓝桥杯备赛 | 洛谷做题打卡day13题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示样例说明数据规模与约定 思路:方程: 题解代码我的一些话 [USACO2006 OPEN] 县集市 The County Fair 题目描述 每年…...

C#,入门教程(30)——扎好程序的笼子,错误处理 try catch
上一篇: C#,入门教程(29)——修饰词静态(static)的用法详解https://blog.csdn.net/beijinghorn/article/details/124683349 程序员语录:凡程序必有错,凡有错未必改! 程序出错的原因千千万&…...

操作教程|JumpServer堡垒机结合Ansible进行批量系统初始化
运维人员常常需要对资产进行系统初始化的操作,而初始化服务器又是一项繁琐的工作,需要花费运维人员大量的时间和精力。为了提高效率,许多组织会使用自动化工具和脚本来简化这些任务。自动化工具的运用可以大幅降低运维人员的工作量࿰…...

序列化VS反序列化
序列化、反序列化定义 如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。 序列化(Serialization)是指将对象转换为字节序列的过程,也可以称之为对象的持…...

新数智空间:阿里云边缘云持续保持中国公有云市场第一
全球领先的 IT 市场研究和咨询公司 IDC 发布 《中国边缘云市场解读(2023H1)》报告 中国边缘公有云服务市场 阿里云持续第一 稳居市场第一,“边缘”逆势生长 近日,全球领先的 IT 市场研究和咨询公司 IDC 最新发布《中国边缘云市…...

【开源】基于JAVA语言的陕西非物质文化遗产网站
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与过程2.3.1 系统设计2.3.2 查阅文献2.3.3 网站分析2.3.4 网站设计2.3.5 网站实现2.3.6 系统测试与效果分析 三、系统展示四、核心代码4.1 查询民间文学4.2 查询传统音乐4.3 增改传统舞…...

C++(Qt)软件调试---静态分析工具clang-tidy(18)
C(Qt)软件调试—静态分析工具clang-tidy(18) 文章目录 C(Qt)软件调试---静态分析工具clang-tidy(18)1、概述2、clang-tidy基本用法3、目前已有检查项4、Qt Creator中安装clang-tidy5、Qt Creator中使用clang-tidy6、Clang-Tidy配置…...

2401llvm,clang的重构引擎
Clang的重构引擎 展示如何使用重构API中的各种原语来实现不同的重构. LibTooling库提供了几个在开发重构操作时,使用的其他API. 可用重构引擎来实现,用编辑器或IDE中的选择启动的本地重构.可结合AST匹配器和重构引擎,以实现不适合源选择和/或必须查询某些指定节点的AST的重构…...

【C语言深度剖析——第四节(关键字4)】《C语言深度解剖》+蛋哥分析+个人理解
追求本质,不断进步 本文由睡觉待开机原创,转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 这里写目录标题 一、空间的申请1.变量定义1.1变量定义的概念:1.2变…...

鸿蒙开发系列教程(五)--ArkTS语言:组件开发
1、基础组件 组件API文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…...

Java:正则表达式讲解加举例,简洁易懂
正则表达式定义: 由一些特定的字符组成,代表的是一个规则。 作用:1.校验数据是否合法。2.可以在一段文本中查找满足要求的内容。 先自己写一个方法去校验qq号,比较与正则表达式的区别: 正则表达式的代码暂时可以不…...

2.机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解
2️⃣机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解 个人简介一算法概述二算法思想2.1 KNN的优缺点 三实例演示3.1电影分类3.2使用KNN算法预测 鸢(yuan)尾花 的种类3.3 预测年收入是否大于50K美元 个人简介 🏘️&…...

WordPress顶部管理工具栏怎么添加一二级自定义菜单?
默认情况下,WordPress前端和后台页面顶部都有一个“管理工具栏”,左侧一般就是站点名称、评论、新建,右侧就是您好,用户名称和头像。那么我们是否可以在这个管理工具栏中添加一些一二级自定义菜单呢? 其实,…...

Linux安装ossutil工具且在Jenkins中执行shell脚本下载文件
测试中遇到想通过Jenkins下载OSS桶上的文件,要先在linux上安装ossutil工具,记录安装过程如下: 一、下载安装ossutil,使用命令 1.下载:wget https://gosspublic.alicdn.com/ossutil/1.7.13/ossutil64 2.一定要赋权限…...

Docker命令---搜索镜像
介绍 使用docker命令搜索镜像。 命令 docker search 镜像命令:版本号示例 以搜索ElasticSearch镜像为例 docker search ElasticSearch...

docker使用http_proxy配置代理
钢铁知识库,一个学习python爬虫、数据分析的知识库。人生苦短,快用python。 在内网服务器中,docker经常需要下载拉取镜像,但由于没有网络要么只能手动导入镜像包,又或者通过http_proxy代理到其它服务器下载。 解决方法…...

综述:自动驾驶中的 4D 毫米波雷达
论文链接:《4D Millimeter-Wave Radar in Autonomous Driving: A Survey》 摘要 4D 毫米波 (mmWave) 雷达能够测量目标的距离、方位角、仰角和速度,引起了自动驾驶领域的极大兴趣。这归因于其在极端环境下的稳健性以及出色的速度和高度测量能力。 然而…...