spring源码分析-事务的底层源码-1

news2024/11/18 10:51:25

这里写自定义目录标题

  • spring事务的源码分析
    • 阅读spring事务源码的前置知识
    • JDBC的事务
    • spring当中和事务相关的对象
    • spring应用程序编码
    • spring事务的源码如何开始研究
    • spring源码当中如何代理bean

spring事务的源码分析

最近在研究seata;看了一下spring当中的事务有一点心得故而来写篇文章分享一下;另外对于seata框架的视频讲解在b站上;如果对seata比较感兴趣的可以去三连一下;还有就是关于这篇文章对应的视频讲解我也传到这个b站账号上;
https://space.bilibili.com/419779862

阅读spring事务源码的前置知识

spring事务这块代码写的有点复杂;如果需要完全看懂需要一点点前置知识;

  • JDK动态代理的知识
  • spring bean生命周期和后置处理器的一些知识
  • spring Aop的原理

当然如果你不具备这些知识也没关系知识读起来会难一点;其中关于JDK动态代理的知识我曾经录过一个2小时的手写JDK动态代理的视频;如果你对JDK动态代理不是很了解可以评论区问一下看完一定会非常清晰;当然你如果嫌麻烦就可以直接看下图;记住图中的结论(如果你懂动态代理可以不用看图了);

在这里插入图片描述

JDBC的事务

正常情况下spring的事务是基于jdbc的事务来的;那么我们现在回顾一下jdbc的事务代码;其实非常简单;

onnection connection = getConnection();
connection.setAutoCommit(false);
//执行sql等等操作
//执行完成之后提交
connection.commit();
connection.rollback();

其实你仔细想一下会发现事务他是一个非常难以抽象的概念;比如一个苹果你去抽象可以定义一个类Apple;然后定义一些属性——产地、颜色、价格、口味等等;但是事务这个东西他不是一个名词,严格意义上他是一个动作,甚至不是一个动作是一些列动作(提交、或者回滚);那么作为spring作者他该如何在spring源码当中来抽象呢?——说白了就是该定义一个怎样的类来描述事务这个东西呢?诚如前面说的事务是一个动作spring框架要抽象出来比较困难;所以如果想搞懂spring源码当这块的代码需要先搞明白关于事务的一些对象在spring当中;

spring当中和事务相关的对象

这块相当重要;如果想把spring源码当中对事务的操作代码看懂就一定得先好好看看这一章节;当然这里可能阅读起来很麻烦甚至你看不懂;但是你一定硬着头皮看下去我尽量写详细一点;

1、首先spring如果需要操作事务离不开JDBC那一套——也就是首先的需要获取连接;但是spring当中默认认为你是使用了数据源;也就是DataSource;spring当中定义了一个类TransactionManager——事务管理器里面保存了数据源;这里面的dataSouce需要程序员手动配置给他;相信你如果做过spring开发就写过这行代码
在这里插入图片描述
2、数据源不代表连接;具体的连接对象spring当中有一个类DataSourceTransactionObject这个当中包含了Connetion对象;下面是我对这个类属性的总结,实际spring源码当中封装了很多层;后面再来详细说;这里只是先列举出来方便我们理解spring作者在设计事务这块的思路和类的设计

DataSourceTransactionObject{
	previousIsolationLevel;隔离级别
	savepointAllowed;是否允许savepoint
	currentConnection;连接
	transactionActive;事务是否活跃
	mustRestoreAutoCommit;是否需要重置自动提交
	Connection currentConnection;连接信息
}

3、事务状态的包装;spring当中事务是否只读;事务是否完成;事务是否同步;事务是否是一个新的事务等等这些信息用了一个TransactionStatus的类来封装

TransactionStatus{//事务的状态
	boolean rollbackOnly = false;//是否只读事务
	boolean completed = false;//是否完成
	Object savepoint;底层数据库支持
	newTransaction; 是否新开的事务
	newSynchronization 是否同步
}	

4、事务的属性,也就是程序在定义事务指定的特点,比如传播机制、比如事务的回滚异常;是否需要指定隔离级别等等在sping当中定义了一个类TransactionAttribute来封装

5、上面四个类怎么关联起来呢?spring当中定义了一个类TransactionInfo他把上面四个类关联起来了;如果上面你没用看懂;你现在就记住一个结论;就是spring在操作事务的时候他最后需要得到一个TransactionInfo的对象;通过这个对象去作判断,比如传播机制是否合理,比如异常是否匹配等等行为去提交事务或者回滚事务;这五个类的关系大体如下面

	TranscationInfo{ //事务信息 包含了事务的所有操作和信息
		TransactionAttr;//事务属性--程序员配置
		TransactionManager//事务管理器,包含了数据源
		TransactionStatus{//事务的状态
			boolean rollbackOnly = false;//是否只读事务
			boolean completed = false;//是否完成
			Object savepoint;底层数据库支持
			private final Object transaction;//
			newTransaction; 是否新开的事务
			newSynchronization 是否同步	
			DataSourceTransactionObject//和数据源关联的事务对象
				DataSourceTransactionObject{
						previousIsolationLevel;隔离级别
						savepointAllowed 是否允许savepoint
						currentConnection;连接
						transactionActive;事务是否活跃
						mustRestoreAutoCommit;是否需要重置自动提交
				}
			
		}
}

之所以现在就列举这几个对象,是因为这几个对象很重要了,spring底层源码关于事务这块基本就是操作这几个对象,读者可以先看个大概,如果看不懂可以直接记住我上面的结论——就是spring在操作事务的时候他最后需要得到一个TransactionInfo的对象;通过这个对象去作判断,比如传播机制是否合理,比如异常是否匹配等等行为去提交事务或者回滚事务;

spring应用程序编码

当然要研究事务需要一个案例;spring+mybatisplus+mysql;代码我传到文章末尾——需要说明的是我是基于spring源码这个项目搭建的环境所以是gradle,如果下载我的代码需要改对应的比如maven;这里对代码做一个简单介绍
1、数据源代码–使用spring自带的需要在配置类当中写代码;mybatis的配置就不在文章当中说明了,参考我传的附件demo

@Bean
	public DataSource dataSource(){
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/cloud_demo?useUnicode=true&rewriteBatchedStatements=true");
		dataSource.setUsername("root");
		dataSource.setPassword("aaa111");
		return dataSource;
	}

2、如果要开启spring的声明式事务的支撑需要配置一个事务管理器;事务管理器需要设计一个数据源给他;原因上文做了说明

@Bean
	public DataSourceTransactionManager dataSourceTransactionManager(){
		DataSourceTransactionManager dstm = new DataSourceTransactionManager();
		dstm.setDataSource(dataSource());
		return dstm;
	}

3、在配置类上面开启允许事务;

@Configuration
@EnableTransactionManagement
public class Appconfig {
}

@EnableTransactionManagement这个注解底层原理非常重要,下文会详细说明

4、在对应的方法上面加上@Transcation注解

@Service
public class InventoryAtService{}
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean save(InventoryEntity entity) {
	}
}

那么InventoryAtService这个类就会被spring代理,增强其中的save方法在save方法当中加上事务的逻辑

spring事务的源码如何开始研究

其实研究spring是的事务原理无非两个大的问题
1、spring是如何完成拦截和增强的;譬如上面InventoryAtService sprring是如何拦截到这个类的;如何完成增强的

2、增强的逻辑是什么?也就是他怎么开启事务,怎么提交事务,怎么回滚事务?

首先解决第一个问题;spring是如何拦截到需要被增强的类——换句话说spring是如何拦截到方法上加了@Transactional的类并且增强的;但凡有点spring知识肯定知道这是springaop机制;关键是aop需要配置切面、切点、通知、连接点等等;而我们这里是没有配置切面、没有配置切点、没有配置通知的;

1、首先通知其实是不需要我们配置的,因为事务这块的通知肯定spring框架自己写的——关于开启提交事务的代码;这块业务代码不可能交给程序员去写;所以通知肯定是spring内置的;

2、那么切面和切点呢?回滚一下如果程序员自己定义切面的Aspectj语法是需要新建一个类,然后再里面写代码去配置;然后spring会把这些切面当中的信息——通知、切点、连接点封装成为一个Advisor对象;所以如果你不手动配置切面你也可以给spring提供一个Advisor对象也能完成aop的定义

3、spring事务增强这块就是他提供了一个Advisor对象里面把切面的各种信息封装了,所以不需要你手动去写Aspectj语法风格的切面了;

4、那么这个对象在哪里呢?怎么生效的呢?—@EnableTransactionManagement;查看这个注解的源码
在这里插入图片描述

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
}

5、EnableTransactionManagement 当中会Import一个类TransactionManagementConfigurationSelector.class;查看这个类的源码

在这里插入图片描述

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

6、TransactionManagementConfigurationSelector 这个类一看就是实现了ImportSelector接口;这个接口有一个方法 selectImports会返回一个字符串数组;如果字符串数组的内容是一个符合标准的全限定类名;那么spring会把这个类当做一个bean去进行实例化和初始化到容器当中——其实springboot的自动装配功能就是利用了这个spring提供的扩张点;关于ImportSelector我曾经讲过一个50小时的spring源码视频可以直接找博主要这里不在累述;你只需要记住一个结论——selectImports方法当中返回的字符串如果是正常的全限定类名则会被容器识别

7、观察TransactionManagementConfigurationSelector 当中的selectImports方法


	return new String[] {
	AutoProxyRegistrar.class.getName(),
	ProxyTransactionManagementConfiguration.class.getName()	
	}

主要返回了两个类AutoProxyRegistrar和ProxyTransactionManagementConfiguration;接下来一个一个分析

8、AutoProxyRegistrar 查看源码
在这里插入图片描述
在他的registerBeanDefinitions方法当中注册了一个beanDefintion

在这里插入图片描述

接着点进去查看源码

在这里插入图片描述

这里主要注册了一个类InfrastructureAdvisorAutoProxyCreator;查看这个类的源码;
在这里插入图片描述

发现他其实是一个BeanPostProcessor并且他是集成至AbstractAutoProxyCreator;那么就是一个完成代理的后置处理器;和AOP类似——说白了InfrastructureAdvisorAutoProxyCreator理论上会对所有的bean进行代理、为什么是理论上呢?因为实际过程中他在处理bean的时候会做一些条件判断;所以是理论上;那么做什么判断呢?其实这属于AOP的知识,也就是springAOP在完成代理的时候会进行切面当中的连接点信息判断是否需要增强;这里也是一样——判断bean是否符合连接点的配置,至于连接点的信息在下一个类当中;至此导入的第一个类AutoProxyRegistrar的作用解释清楚了

return new String[] {
	AutoProxyRegistrar.class.getName(),//解释清楚了
	ProxyTransactionManagementConfiguration.class.getName()	
	}

9、连接点在哪里设置的?InfrastructureAdvisorAutoProxyCreator会增强bean;但是需要提供连接点或者切点信息;这些信息就是第二个类ProxyTransactionManagementConfiguration当中去设置的

查看这个类的源码;这个类的源码比较多,我们一点点解释

在这里插入图片描述

@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		advisor.setAdvice(transactionInterceptor);
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

首先这个类当中第一个方法是一个加了@Bean的方法 返回一个 BeanFactoryTransactionAttributeSourceAdvisor类型的bean;我们先不去关系这个bean;先看这个方法的参数;他有两个参数;
1、TransactionAttributeSource transactionAttributeSource,
2、TransactionInterceptor transactionInterceptor

在这里插入图片描述
由于这是个@Bean方法所以这两个参数也是回去spring容器获取;所以这两个参数对应肯定也是一个bean;spring在下面又写了两个@Bean方法来实例化这两个bean

在这里插入图片描述

这两个bean是干嘛的?
第一个 TransactionAttributeSource 这个bean的作用主要将来用来获取事务属性的;比如你配置的传播机制,异常信息等等;这个bean当中提供了一个方法来获取这些信息

第二个:TransactionInterceptor ;这个相当重要;他是一个方法拦截器;他里面有个invoke方法;——相当于通知;也就是将来你对bean进行代理,对方法进行增强的时候的增强逻辑——放到这里就是事务的开启、提交、回滚都会写在这对象的invoke方法当中;当然这里他仅仅是个bean;他是怎么成为一个通知的呢?

回到BeanFactoryTransactionAttributeSourceAdvisor这个bean,我们前面说了他需要两个参数,上面解释了他两个参数的作用;接下来解释这个类,这个类去查看他的源码发现他就是一个advisor;也就是他里面应该包含切点、通知、连接点信息;所以他需要一个TransactionInterceptor 类型的参数,作为他的通知;
在这里插入图片描述
那么他的切点和连接点在哪里呢?查看这个类的源码他里面定义了一个属性

在这里插入图片描述

这个切点对象就是后续spring在增强时候需要用到的,他提供的一个匹配方法,来判断当前bean是否符合切点信息——而且这个切点对象当中的规则就是判断方法是否加了Transactional注解——这个判断逻辑下文分析 这里给出一个spring源码截图的证据
在这里插入图片描述

至此:@EnableTransactionManagement 这个注解的功能都搞清楚了;
总结一下这个注解主要两个作用
1、导入了一个后置处理器对象来增强bean ——InfrastructureAdvisorAutoProxyCreator
2、导入了一个Advisor对象;主要是定义好了哪些bean需要增强,增强的逻辑是什么;接下来分析如何应用起来的

spring源码当中如何代理bean

在这里插入图片描述
上图所示当调用inventoryService的save方法的时候,假设inventoryService没有实例化,那么spring容器会实例化这个bean,会走他的生命周期,当走到BeanPostProcessor的postProcessAfterInitialization方法的时候会从容器当中拿出所有的后置处理器依次执行他们的postProcessAfterInitialization方法;关于这块属于bean的生命周期知识可以参考我前面写的循环依赖文章;前文已经分析过了@EnableTransactionManagement 注解会往容器当中注册一个后置处理器——InfrastructureAdvisorAutoProxyCreator那么这个后置处理会在这里起到作用;
在这里插入图片描述
getBeanPostProcessors()就是获取到所有的后置处理器;我们前面通过@EnableTransactionManagement 导入的那个后置处理器就会出现在这里;换言之如果不加那个注解,那么你的@Transcation注解就不会生效,因为你不加注解容量当中没有InfrastructureAdvisorAutoProxyCreator这后置处理器,就无法对bean进行代理;
在这里插入图片描述
那么在InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization当中如何对bean进行代理的呢?

在这里插入图片描述
InfrastructureAdvisorAutoProxyCreator会调用父类的postProcessAfterInitialization方法内部会调用wrapIfNecessary方法完成代理;这里说明一下其实循环依赖当中不止三个map也就是网上所谓的三级缓存其实不够严谨,严格意义是四个map还有就是上图我写了注释的地方——earlyProxyReferences;这里不在详细说了将来可以再写一篇文章来详细说说这个问题;

接下来查看wrapIfNecessary方法;里面代码属于aop源码的部分;我曾经在讲过spring源码这里不在详细说只拎取和本文相关的代码作说明

在这里插入图片描述

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

getAdvicesAndAdvisorsForBean方法非常重要;顾名思义就是通过当前bean(inventoryService)找到与之对应的Advisor——说白了就是找到定义了需要增强当前bean的Advisor;前文说了Advisor相当于切面,里面定义了切点和连接点,如果连接点符合当前bean,那么就会把这个Advisor找出来;那么这里能不能找到呢?看一下源码

在这里插入图片描述
调用AbstractAdvisorAutoProxyCreator当中getAdvicesAndAdvisorsForBean方法,改方法里面继续调用findEligibleAdvisors

在这里插入图片描述
findEligibleAdvisors方法里面的内容有点多,我们逐行解释;
1、首先调用List candidateAdvisors = findCandidateAdvisors();找到所有的Advisor;不管符不符合当前bean都找出来;比如你定义了一个Advisor可能是给OrderSerivice服务的但是也会在这里找出来;可以查看他里面的源码
在这里插入图片描述
2、找打所有的Advisor之后把他们存入一个List当中然后返回;并且把这个list在进行遍历找出符合当前bean需求的advisor
在这里插入图片描述
findAdvisorsThatCanApply方法就是遍历并判断哪些Advisor对象能服务当前对象;里面代码最核心

在这里插入图片描述
上面是个空壳方法继续调用findAdvisorsThatCanApply
在这里插入图片描述

这里有一个是否IntroductionAdvisor类型的判断;关于Introduction——AOP我有讲过这里不在累述;你可以理解这个基本不会成立;所以会进到322行的if当中执行canApply方法

在这里插入图片描述
继续执行289行代码

在这里插入图片描述
这里的代码比较复杂;首先获取了一个MethodMatcher对象;是通过pc对象获取的,这里的pc对象其实就是我们前面通过@EnableTransactionManagement这个注解导入的Advisor对象——BeanFactoryTransactionAttributeSourceAdvisor当中的切点对象;怎么理解呢?看懂下面这幅图

在这里插入图片描述

最后methodMatcher.matches(method, targetClass))调用的就是TransactionAttributeSourcePointcut类当中的matches方法

在这里插入图片描述
然后执行
在这里插入图片描述

跟着执行
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

最后执行
在这里插入图片描述
至此spring就能找到所有加了@Transcation注解的方法所在的类,并且对其进行代理;

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

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

相关文章

CASA模型在陆地生态系统碳循环研究中的应用探讨

植被&#xff0c;作为陆地生态系统的重要基石&#xff0c;对维护生态环境功能具有不可替代的作用。其中&#xff0c;植被净初级生产力&#xff08;NPP&#xff09;是衡量植被生态系统健康与功能的关键指标。它反映了单位面积上绿色植被通过光合作用生产的有机质总量在扣除自养呼…

ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件)

ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件) 今天借助[小蜜蜂AI][https://zglg.work]网站的ChatGPT编程实现一个功能&#xff1a;批量处理文件及其内容&#xff0c;例如批量替换文本、批量处理图像文件等。 环境&#xff1a;Pycharm 2021 系统&#xff1a…

西门子TIA中配置Anybus PROFINET IO Slave 模块

1、所需产品 Siemens S7 PLC CPU 315-2 PN/DP 6ES7 315-2EH-0AB0 Siemens PLC 编程电缆 n.a. n.a. PC ,并安装Siemens PLC编程软件 TIA Portal V11 X-gateway Slave 接口的GSDML文件 根据网关的软件版本而定 Anybus Communicator GSD文件 GSDML-V1.0-HMS-ABCPRT-20050317.xl…

腾讯云2核4g服务器能支持多少人访问?没搞错吧

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

kkview远程控制: 内网远程桌面控制软件

内网远程桌面控制软件&#xff1a;高效、安全的远程管理方案 在信息技术日新月异的今天&#xff0c;内网远程桌面控制软件已成为许多企业和个人用户不可或缺的工具。这类软件允许用户通过内部网络&#xff0c;实现对其他计算机的远程访问和控制&#xff0c;从而大大提高工作效…

2024年高处安装、维护、拆除证模拟考试题库及高处安装、维护、拆除理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年高处安装、维护、拆除证模拟考试题库及高处安装、维护、拆除理论考试试题是由安全生产模拟考试一点通提供&#xff0c;高处安装、维护、拆除证模拟考试题库是根据高处安装、维护、拆除最新版教材&#xff0c;高…

Radware DDoS防护迎来重大升级,重拳出击在线游戏行业难题

日前&#xff0c;全球领先的网络安全和应用交付解决方案提供商Radware推出了多维DDoS检测和防护措施&#xff0c;以满足在线游戏行业独特复杂的需求。Radware开发了一系列新的算法来保护在线游戏免遭复杂攻击。 Radware首席运营官Gabi Malka表示&#xff1a;“在线游戏是价值数…

车联网应用:开箱即用的物联网卡管理平台

IoTLink是物联网卡管理平台&#xff0c;采用SpringBoot、Vue、Mybatis等技术&#xff0c;支持多渠道管理&#xff0c;提供物联卡数据采集和云端SaaS服务。功能包括物联卡、模组管理、业务告警、微信端操作等。工厂项目可利用该平台管理物联卡、监控数据&#xff0c;并通过定制功…

论文阅读——Rein

Stronger, Fewer, & Superior: Harnessing Vision Foundation Models for Domain Generalized Semantic Segmentation 一、引言 是一个对Domain Generalized Semantic Segmentation (DGSS)任务的视觉大模型的微调方法&#xff0c;即Rein。 Rein 专为 DGSS 任务量身定制&a…

计算机系统基础 2 Intel 中央处理器

Intel微处理器的发展史 INTegrated ELectronics&#xff08;集成电子&#xff09;的缩写 先后推出的中央处理器&#xff1a; Intel4004、Intel8008、Intel8080/8085、8086/8088、80186、80286、i386、i486 Pentium&#xff08;奔腾&#xff09;、Pentium II、Pentium III、Pen…

军事通信中数字的特殊读法

文心一言 在军事通信中&#xff0c;数字的特殊读法是为了确保在嘈杂、紧张或紧急情况下&#xff0c;信息能够准确无误地传递。这种读法通常遵循一定的规律&#xff0c;使得每个数字都有一个独特的、不易混淆的发音。以下是在军事通信中常见的数字特殊读法&#xff1a; 0 读为…

Java面试题合集-史上最全

3月4月又到了一年一度的跳槽黄金期&#xff0c;无论几年经验&#xff0c;也无论技术能力如何&#xff0c;跳槽前都离不开面试准备&#xff0c;其中刷面试题是重中之重。 刷面试题的时候一大痛点就是太分散了&#xff0c;需要自己根据知识点一项一项的去搜&#xff0c;容易遗漏…

腾讯云2核4G5M云服务器能支持多少并发?

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

页面事件

下拉刷新事件 1. 什么是下拉刷新 下拉刷新是移动端的专有名词&#xff0c;指的是通过手指在屏幕上的下拉滑动操作&#xff0c;从而重新加载页面数据的行为。 2. 启用下拉刷新 启用下拉刷新有两种方式&#xff1a; ① 全局开启下拉刷新  在 app.json 的 window 节点中&…

网络通信与网络协议

网络编程是指利用计算机网络实现程序之间通信的一种编程方式。在网络编程中&#xff0c;程序需要通过网络协议(如 TCP/IP)来进行通信&#xff0c;以实现不同计算机之间的数据传输和共享。在网络编程中&#xff0c;通常有三个基本要素 IP 地址:定位网络中某台计算机端口号port:定…

Java项目:53 springboot校园管理系统的设计与实现014

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 1、关于校园管理系统的基本要求&#xff1a; &#xff08;1&#xff09;功能要求&#xff1a;可以管理首页、个人中心、院校管理、用户管理、单位类别…

【SQLite数据库】的使用

SQLite数据库 文章目录 SQLite数据库0、linux基础知识补充1、SQLite简介1.1 SQLite & MySQL 的优缺点比较1.2 常见的嵌入式数据库 2、数据库的基本命令和用法2.1 创建数据库2.2 创建一张表格2.3 插入一条数据2.4 增加一列2.5 删2.6 改2.7 查看数据库 3、数据库编程3.1 实验…

通过actions configuration tool进行快速open 软件的定义

这个主要是看到有人可以直接在文件夹中右键打开terminator得到的启发&#xff1a; 首先需要下载工具 sudo apt-get install nautilus-actions下载terminator&#xff1a; sudo apt-get install terminator去软件目录寻找filemanager-action 然后新建一个action&#xff0c…

力扣59. 螺旋矩阵 II

思路&#xff1a;此题思路就是绕圈遍历&#xff0c;全靠条件处理技巧&#xff0c;重点要清楚的就是循环不变量&#xff1a;左闭右开&#xff08;即拐弯处的一个数&#xff0c;留给第二行处理&#xff09; 以下是代码随想录的作者的一张图片&#xff0c;每次for循环&#xff0c;…

【计算机组成原理】处理机管理

目录 一、处理机分类 1. MPU 2. MCU 3. DSP 二、CPU的功能 1. 指令控制 2. 操作控制 3. 时间控制 4. 数据加工 三、CPU的组成 &#xff08;一&#xff09;控制器 1. 控制器的功能 &#xff08;1&#xff09;控制指令执行的顺序 ① 程序中规定的转移类型指令 ② …