AOP 操作

news2025/5/20 0:54:17

AOP 操作

  • AOP 操作(准备)
    • 1. Spring 框架一般是基于 AspectJ 实现 AOP 操作
      • (1)什么是 AspectJ
    • 2. 基于 AspectJ 实现 AOP 操作
    • 3. 在项目工程里面引入 AOP 先关的依赖
    • 4. 切入点表达式
      • 举例1:对 com.fairykunkun.dao.UserDao 类里面的 add 进行增强
      • 举例2:对 com.fairykunkun.dao.UserDao 类里面的所有方法进行增强
      • 举例3:对 com.fairykunkun.dao 包里面的所有类的所有方法进行增强
  • AOP 操作( Aspect 注解)
    • 1. 创建一个类,在类里面定义方法
    • 2. 创建增强类(编写增强逻辑)
      • (1)在增强类里面,创建方法,让不同的方法代表不同的通知类型
    • 3. 进行通知的一个配置
      • (1)在 Spring 的配置文件中开启注解的扫描
      • (2)使用注解创建 User 和 UserProxy 对象
      • (3)在增强类上面添加注解 @Aspect
      • (4)在 Spring 配置文件中开启生成代理对象
    • 4. 配置不同类型的通知
      • (1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
      • 5. 测试
      • 6. 总结
      • 7. 公共(相同)切入点抽取
      • 8. 多个增强类对我们的同一个方法进行增强,设置增强类的优先级
      • 9. 完全使用注解开发
  • AOP 操作( AspectJ 配置文件)
    • 1. 创建两个类,增强类和被增强类,创建方法
    • 2. 在 Spring 配置文件中创建两个类对象
    • 3. 在 Spring 配置文件中配置切入点

AOP 操作(准备)

1. Spring 框架一般是基于 AspectJ 实现 AOP 操作

(1)什么是 AspectJ

AspectJ 不是 Spring 组成部分,独立 AOP 框架,一般把 AspectJ 和 Spring 框架一起使用,进行 AOP 操作

2. 基于 AspectJ 实现 AOP 操作

(1)基于 xml 配置文件实现
(2)基于注解的方式实现

3. 在项目工程里面引入 AOP 先关的依赖

<!--aop相关依赖-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>5.3.20</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.9.9.1</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.9.1</version>
</dependency>
<dependency>
	<groupId>org.assertj</groupId>
	<artifactId>assertj-core</artifactId>
	<version>3.23.1</version>
</dependency>

4. 切入点表达式

(1)切入点表达式的作用:知道对哪个类里面的那个方法进行增强
(2)语法结构

execution([权限修饰符][返回类型][全类名][方法名称]([参数列表]))

举例1:对 com.fairykunkun.dao.UserDao 类里面的 add 进行增强

execution(*com.fairykunkun.dao.UserDao.add(..))

举例2:对 com.fairykunkun.dao.UserDao 类里面的所有方法进行增强

execution(*com.fairykunkun.dao.UserDao.*(..))

举例3:对 com.fairykunkun.dao 包里面的所有类的所有方法进行增强

execution(*com.fairykunkun.dao.*.*(..))

AOP 操作( Aspect 注解)

1. 创建一个类,在类里面定义方法

package com.fairykunkun.aopanno;
// 被增强的类
public class User {
	public void add ( ) {
		System.out.println ( "add ..." );
	}
}

2. 创建增强类(编写增强逻辑)

(1)在增强类里面,创建方法,让不同的方法代表不同的通知类型

package com.fairykunkun.aopanno;
// 增强的类
public class UserProxy {
	public void before ( ) {
		// 前置通知
		System.out.println ( "before ..." );
	}
}

3. 进行通知的一个配置

(1)在 Spring 的配置文件中开启注解的扫描

<?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 
	   		http://www.springframework.org/schema/context/spring-context.xsd
	   		http://www.springframework.org/schema/aop
	   		http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- 开启注解的扫描 -->
	<context:component-scan base-package = "com.fairykunkun.aopanno"></context:component-scan>
</beans>

(2)使用注解创建 User 和 UserProxy 对象

package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 被增强的类
@Component
public class User {
	public void add ( ) {
		System.out.println ( "add ..." );
	}
}
package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 增强的类
@Component
public class UserProxy {
	// 前置通知
	public void before ( ) {
		System.out.println ( "before ..." );
	}
}

(3)在增强类上面添加注解 @Aspect

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
	// 前置通知
	public void before ( ) {
		System.out.println ( "before ..." );
	}
}

(4)在 Spring 配置文件中开启生成代理对象

<?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
	   		http://www.springframework.org/schema/context/spring-context.xsd
	   		http://www.springframework.org/schema/aop
	   		http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- 开启注解的扫描 -->
	<context:component-scan base-package = "com.fairykunkun.aopanno"></context:component-scan>
	<!-- 开启 Aspect生成代理对象 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

4. 配置不同类型的通知

(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
	// 前置通知
	// @Before 注解表示作为前置通知
	// * 表示可以返回任意值
	@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void before ( ) {
		System.out.println ( "before ..." );
	}
}

5. 测试

package com.fairykunkun;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fairykunkun.aopanno.User;
public class TestAop {
	@Test
	public void testAopAno ( ) {
		ApplicationContext context =
				new ClassPathXmlApplicationContext ( "bean11.xml" );
		User user = context.getBean ( "user" , User.class );
		user.add ( );
	}
}

实验结果

  • 继续完善增强类的方法
package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
	// 前置通知
	// @Before 注解表示作为前置通知
	// * 表示可以返回任意值
	@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void before ( ) {
		System.out.println ( "before ..." );
	}
	@AfterThrowing ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void afterThrowing ( ) {
		System.out.println ( "afterThrowing......" );
	}
	@After ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void after ( ) {
		System.out.println ( "after......" );
	}	
	// 环绕通知
	@Around ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
		System.out.println ( "环绕之前......" );
		// 被增强的方法执行
		proceedingJoinPoint.proceed ( );
		System.out.println ( "环绕之后......" );
	}
}
  • 再看一下测试结果
package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
	// 前置通知
	// @Before 注解表示作为前置通知
	// * 表示可以返回任意值
	@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void before ( ) {
		System.out.println ( "before ..." );
	}
	@AfterThrowing ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void afterThrowing ( ) {
		System.out.println ( "afterThrowing......" );
	}
	@AfterReturning ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void afterReturning ( ) {
		System.out.println ( "afterReturning......" );
	}
	@After ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void after ( ) {
		System.out.println ( "after......" );
	}
	// 环绕通知
	@Around ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
		System.out.println ( "环绕之前......" );
		// 被增强的方法执行
		proceedingJoinPoint.proceed ( );
		System.out.println ( "环绕之后......" );
	}
}
  • 看一下实验结果
    在这里插入图片描述
  • 在 User 的 add 方法中模拟一个异常
package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 被增强的类
@Component
public class User {
	public void add ( ) {
		int i=10/0;
		System.out.println ( "add ..." );
	}
}
  • 测试
    测试结果

6. 总结

  • @Before(前置通知)
  • @AfterReturning(后置通知,返回通知)
  • @After(最终通知)
  • @Around(环绕通知)
  • @AfterThrowing(异常通知)

7. 公共(相同)切入点抽取

package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
	// 相同切入点抽取
	@Pointcut ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )
	public void pointdemo ( ) {
	}
	// 前置通知
	// @Before 注解表示作为前置通知
	// * 表示可以返回任意值
	@Before ( value = "pointdemo()" )
	public void before ( ) {
		System.out.println ( "before ..." );
	}
	@AfterThrowing ( value = "pointdemo()" )
	public void afterThrowing ( ) {
		System.out.println ( "afterThrowing......" );
	}
	@AfterReturning ( value = "pointdemo()" )
	public void afterReturning ( ) {
		System.out.println ( "afterReturning......" );
	}
	@After ( value = "pointdemo()" )
	public void after ( ) {
		System.out.println ( "after......" );
	}
	// 环绕通知
	@Around ( value = "pointdemo()" )
	public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
		System.out.println ( "环绕之前......" );
		// 被增强的方法执行
		proceedingJoinPoint.proceed ( );
		System.out.println ( "环绕之后......" );
	}
}
  • 把之前做的那个异常去掉,然后再做测试
    实验结果图

8. 多个增强类对我们的同一个方法进行增强,设置增强类的优先级

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class PersonProxy {
	// 前置通知
	@Before  (value = "execution(* com.fairykunkun.aopanno.User.add(..))")
	public void before() {
		System.out.println ("Person Before......" );
	}
}

(1)在增强类上面添加注解@Order(数字类型值),数字类型值越小优先级越高

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(1)
public class PersonProxy {
	// 前置通知
	@Before  (value = "execution(* com.fairykunkun.aopanno.User.add(..))")
	public void before() {
		System.out.println ("Person Before......" );
	}
}
  • 测试
    测试结果

9. 完全使用注解开发

(1)创建配置类,不需要创建 xml 配置文件

package com.fairykunkun.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan ( basePackages = { "com.fairykunkun" } )
@EnableAspectJAutoProxy ( proxyTargetClass = true )
public class AopConfig {
}

AOP 操作( AspectJ 配置文件)

1. 创建两个类,增强类和被增强类,创建方法

package com.fairykunkun.aopxml;
public class Book {
	public void buy ( ) {
		System.out.println ( "buy" );
	}
}
package com.fairykunkun.aopxml;
public class BookProxy {
	public void before ( ) {
		System.out.println ( "before......" );
	}
}

2. 在 Spring 配置文件中创建两个类对象

<?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: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/aop
	   		http://www.springframework.org/schema/aop/spring-aop.xsd
	   		">
	<!-- 创建对象 -->
	<bean id = "book" class = "com.fairykunkun.aopxml.Book"></bean>
	<bean id = "bookProxy" class = "com.fairykunkun.aopxml.BookProxy"></bean>
</beans>

3. 在 Spring 配置文件中配置切入点

<?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: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/aop
	   		http://www.springframework.org/schema/aop/spring-aop.xsd
	   		">
	<!-- 创建对象 -->
	<bean id = "book" class = "com.fairykunkun.aopxml.Book"></bean>
	<bean id = "bookProxy" class = "com.fairykunkun.aopxml.BookProxy"></bean>
	<!-- 配置 aop 增强 -->
	<aop:config>
		<!-- 切入点 -->
		<aop:pointcut id = "p" expression = "execution(* com.fairykunkun.aopxml.Book.buy(..))"/>
		<!-- 配置切面 -->
		<aop:aspect ref = "bookProxy">
			<!-- 增强作用在具体的方法上 -->
			<aop:before method = "before" pointcut-ref = "p"/>
		</aop:aspect>
	</aop:config>
</beans>
  • 测试
package com.fairykunkun;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fairykunkun.aopxml.Book;
public class TestAop {
	@Test
	public void testAopXml ( ) {
		ApplicationContext context =
				new ClassPathXmlApplicationContext ( "bean12.xml" );
		Book book = context.getBean ( "book" , Book.class );
		book.buy ( );
	}
}

测试结果

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

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

相关文章

谈谈自己对依赖注入的理解

1. 絮絮叨叨 1.1 想学习Google Guice 在工作的过程中&#xff0c;发现有名的大数据组件Presto大量使用Google Guice实现各种Module的构建 很多bind(interface).to(implementClass).in(scope)语句&#xff0c;实现接口与实现类的绑定&#xff0c;并指定实现类是单例还是多例 /…

Service的绑定过程

前言 Service的绑定过程将分为两个部分来进行讲解&#xff1b;分别是Contextlmpl到AMS的调用过程和Service的绑定过程。 frameworks/base/core/java/android/content/ContextWrapper.javapublic boolean bindService(Intent service, ServiceConnection conn,int flags) {ret…

计算机毕设Python+Vue-新型冠状病毒防控咨询网站(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

根据端口划分虚拟局域、集线器、中继器、交换机、路由器、网桥----计算机网络

集线器&#xff1a; 连接计算机和交换机&#xff0c;类似于多台中继器。 实现多台电脑的同时使用一个进线接口来上网或组成局域网 中继器&#xff1a; 连接两条电缆&#xff0c;作用是放大前一条电缆里面的信号并传入下一条电缆。 是对接收到的信息进行再生放大&#xff0c;以…

Jenkins + Jmeter + Ant 持续集成

搭建提前安装好&#xff1a;ant Jenkins 环境 一、Jenkins 安装 Ant 插件&#xff1a; 进入Jenkins 配置插件页面&#xff0c;安装ant 插件&#xff1a; 打开插件配置页面&#xff0c;如下图&#xff1a; 点击“Available” 在输入框搜索 ant 安装即可&#xff1a; 二、安装…

计算机毕业设计springboot+vue基本微信小程序的透析耗材管理系统

项目介绍 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理程序应运而生,各行各业相继进入信息管理时代,透析耗材管理小程序就是信息时代变革中的产物之一。 任何程序都要遵循…

vue前端案例教学:动态获取最新疫情数据展示(代码详解)

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…

[leetcode.4]寻找两个正序数组的中位数 多思考边界

题目展示 题目要点 题目其实本身的思路非常简单&#xff0c;就是把两个数组给合并起来&#xff0c;然后寻找中位数&#xff0c;具体可以参考我们使用归并排序时候的最后一步&#xff0c;这题的难点其实在于&#xff08;1&#xff09;时间压缩到lognm&#xff08;2&#xff09;…

[附源码]Nodejs计算机毕业设计基于与协同过滤算法的竞赛项目管理Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

基于MMEngine和MMDet搭建目标跟踪框架MMTracking-1.0.0rc1-Win10

缘由&#xff1a; 1. 目标跟踪是工业检测和学术研究的基础课题&#xff0c;其pipeline通常分为视频目标检测、视频实例分割、单目标跟踪、多目标跟踪和Re-ID五类&#xff0c;同时&#xff0c;还细分为在线检测和离线检测两种任务模式。由于现阶段关于目标跟踪的教程较少&#…

机器学习 KNN算法原理

目录 一&#xff1a;KNN算法概念 二&#xff1a;KNN原理 三&#xff1a;KNN超参数 四&#xff1a;KNN算法选择 一&#xff1a;KNN算法概念 KNN(K-Nearest Neighbor)法即K最邻近法&#xff0c;最初由Cover和Hart于1968年提出&#xff0c;是最简单的机器学习算法之一 算法思路…

NNDL 作业9:分别使用numpy和pytorch实现BPTT

6-1P&#xff1a;推导RNN反向传播算法BPTT. 6-2P&#xff1a;设计简单RNN模型&#xff0c;分别用Numpy、Pytorch实现反向传播算子&#xff0c;并代入数值测试.、 forward&#xff1a; 我们知道循环卷积网络的cell的计算公式为&#xff1a; stf(UxtWst−1)\mathrm{s}_tf(…

UML学习入门

UML 举一个简单的例子&#xff0c;来看这样一副图&#xff0c;其中就包括了UML类图中的基本图示法。 首先&#xff0c;看动物矩形框&#xff0c;它代表一个类&#xff08;Class&#xff09;。类图分三层&#xff0c;第一层显示类的名称&#xff0c;如果是抽象类&#xff0c;则…

多模块之前的消息引用问题

多模块引用之前的问题目录概述需求&#xff1a;设计思路实现思路分析1.在第一个模块中调用另一个调用模块的Bean2.普通java类 如何获取另一个模块的Bean3.启用消息机制4.为什么普通java类很难调用SpringBean的&#xff1f;参考资料和推荐阅读Survive by day and develop by nig…

机器学习快速上手基础

努力是为了不平庸~ 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。 目录 一、简介与应该明确的学习方法 1、学习方法 2、简介 二、学习机器学习的优势 三、机器学习的内核 1、学习术语 2、内核 四、机器学习…

IT团队自动化端点管理解决方案—基于虹科Chef工具

企业如何简化端点管理工作流程&#xff1f; 如何解决安全事件&#xff1f;如何生成审计报告&#xff1f;如何处理大量账单&#xff1f;这些都是企业IT团队需要考虑的问题。然而&#xff0c;IT人员每天有大量的事情需要处理&#xff0c;如何自动化、标准化、及时性的处理这些问…

(最优化理论与方法)第六章无约束优化算法-第二节:梯度类算法

文章目录一&#xff1a;次梯度算法&#xff08;1&#xff09;次梯度算法结构&#xff08;2&#xff09;应用举例-LASSO问题求解二&#xff1a;牛顿法&#xff08;1&#xff09;经典牛顿法&#xff08;2&#xff09;修正牛顿法三&#xff1a;拟牛顿法&#xff08;1&#xff09;拟…

知到/智慧树——英语听说:实境主题与技能(参考答案)

目录 第一章测试 第二章测试 第三章测试 第四章测试 第五章测试 第六章测试 第七章测试 第八章测试 第九章测试 第十章测试 第一章测试 第1部分总题数: 10 1 【多选题】 (10分) What does this chapter mainly teach &#xff08; &#xff09;&#xff1f; A. T…

生成树(基础)

目录 一、生成树的相关概念 二、最小生成树的相关概念 最小生成树的性质(MST性质)&#xff1a; MST性质解释&#xff1a; 三、Prim算法&#xff08;普里姆算法&#xff09; 动态演示 关键算法&#xff1a; 完整代码&#xff1a; 四、Kruskal(克鲁斯卡尔)算法 动态演示&…

mysql主从复制架构

MySQL的主从复制架构的分布机制&#xff0c;是通过将MySQL的某一台主机(master)的数据复制到其他主机(slave)上。 在复制过程中一台主机作为主服务器&#xff0c;其他服务器则为从服务器。主服务器将更新写入到日志文件中&#xff0c;日志被从服务器的 I/O线程读取&#xff0c;…