SpringBoot源码学习3——SpringBoot启动流程

系列文章目录和关于我

一丶前言

在 《SpringBoot源码学习1——SpringBoot自动装配源码解析+Spring如何处理配置类的》中我们学习了SpringBoot自动装配如何实现的,在 《Spring源码学习笔记12——总结篇IOC,Bean的生命周期,三大扩展点》我们总结了Spring IOC的底层原理。

但是我们还是不知道SpringApplication.run(主类.class, args)到底做了哪些事情。本文将和大家一起看看SpringBoot启动的大致流程,探讨SpringBoot留给我们的扩展接口

二丶SpringBoot启动流程分析

image-20230118213312159

上面是SpringBoot调用SpringApplication.run(主类.class, args)启动的源码,源码并不复杂,整体流程大概如下

image-20230118213655977

下面我们依据此图,看看这些步骤SpringBoot底层源码

1.获取SpringApplicationRunListener实现类,包装成SpringApplicationRunListeners

image-20230118213933916

  • SpringApplicationRunListener是SpringBoot框架中的监听器,在SpringBoot启动到达对应阶段的时候,会回调starting,started等方法。

    为什么SpringBoot不适应Spring 里面的ApplicationListener昵,因为ApplicationListener依赖于Spring容器,@EventListener注解需要EventListenerMethodProcessor这个BeanFactoryPostProcessor扫描,将对应的bean和方法包装成ApplicationListener注册到ApplicationContext中(最终注册到ApplicationEventMulticaster事件多播器中)对于ApplicationListener类型bean则直接走注册到ApplicationContext的流程,整个流程只有Spring 容器启动后才能进行,如果没有SpringApplicationRunListener则开发者无法在SpringBoot启动对应阶段进行一些扩展逻辑的回调。

  • SpringApplicationRunListeners 可以看成是SpringApplicationRunListener的门面(门面设计模式)

其使用List<SpringApplicationRunListener>持有所有的SpringApplicationRunListener,然后starting等方法都是循环调用,集合中SpringApplicationRunListener对应的方法

image-20230118214801860

image-20230118214958185

  • SpringBoot如何获取所有的SpringApplciationListener

    image-20230118215153502

    这里将从META-INF/spring.factories获取org.springframework.boot.SpringApplicationRunListener 定义的实现类全限定类名,然后反射调用构造方法(SpringApplication application, String[] args)进行实例化。随后将根据@Order 或者 Ordered接口定义的顺序进行排序,然后包装成SpringApplicationRunListeners

    image-20230118215449974

    注意无法使用@Component注解 标注在SpringApplciationListener注解上,来实现事件的监听,必须在META-INF/spring.factories中定义,并且必须具备构造方法(SpringApplication application, String[] args)

  • EventPublishingRunListener

    image-20230118215948246

    SpringApplication#addListeners 允许我们注册ApplicationListener到SpringBoot中,然后EventPublishingRunListener其内部会new 一个简单的事件多播器SimpleApplicationEventMulticaster,在对应的SpringBoot启动阶段,推送事件。下面式如何注册ApplicationListener

    image-20230118220126682

    注意这些ApplicationListener不会被注册到Spring上下文中,意味着不会响应Spring上下文推送的事件,除非这个ApplicationListener是一个Spring Bean 并且被Spring管理。

    下图是EventPublishingRunListener在SpringBoot启动的不同阶段,推送事件

    image-20230118220607326

2.SpringApplicationListeners#starting

image-20230118220739167

没啥好说的,循环回调SpringApplicationRunListener#starting方法

3.prepareEnvironment 根据项目选择Environment实现类,并实例化

在这一步,SpringBoot会根据类路径中的类选择一个Environment并实例化,并且根据当前激活的配置,选择对应的配置文件,进行解析,并保存到Environment中。下面是SpringBoot选择Environment的源码

image-20230118221247623

那么SpringBoot是如何判断当前项目是什么应用类型昵?

其实根据类路径下是否具备指定的类,然后得到指定类型,一般我们都是servlet应用,会选择StandardServletEnvironment

image-20230118221500605

4.SpringApplicationListeners#environmentPrepared

2.SpringApplicationListeners#starting

5.createApplicationContext

根据类路径指定类推断使用什么ConfigurableApplicationContext(一般servlet应用使用AnnotationConfigServletWebServerApplicationContext)然后实例化AnnotationConfigServletWebServerApplicationContext

AnnotationConfigServletWebServerApplicationContext#onRefresh方法在Spring容器刷新后会被调用,这个方法将启动Tomcat内嵌服务器

6.prepareContext

这个方法主要会做以下操作

  • 回调ApplicationContextInitializer#initialize
  • 回调所有SpringApplicationRunListener#contextPrepared
  • 将主类包装成BeanDefinition,注册到Spring容器上下文中
  • 回调所有SpringApplicationRunListener#contextLoaded

利用SpringApplicationRunListeners回调SpringApplicationRunListener,同2,不在赘述

6.1从META-INFO/spring.factories中拿所有ApplicationContextInitializer然后回调initialize方法

image-20230118223132300

在spring上下文refresh方法调用前,会回调initialize方法

image-20230118223118520

这里调用前还会判断ApplicationContextInitializer定义的泛型,保证5这一步创建的上下文,符合泛型的要求

6.2 将主类包装成BeanDefinition,注册到Spring容器上下文中

这一步非常重要,主类上的注解@SpringBootApplication需要ConfigurationClassPostProcessor解析,才能发挥@Import,@ComponentScan的作用,想要ConfigurationClassPostProcessor处理主类的前提是主类的BeanDefinition需要在Spring容器中。

也就是说SpringBoot的自动装配,和扫描包路径下的Spring 组件的前提是,主类的BeanDefinition在Spring容器中

image-20230118225311194

这里的BeanDefinitionRegistry,其实就是来自5这一步的ApplicationContext,一般来说AnnotationConfigServletWebServerApplicationContext内部持有了一个DefaultListableBeanFactory,DefaultListableBeanFactoryBeanDefinitionRegistry的实现类,其底层使用一个ConcurrentHashMap维护,key是bean的名称,value是对应的BeanDefinition

image-20230118230101275

当资源是一个Class的时候,会使用AnnotatedBeanDefinitionReader读取Class对象,生成BeanDefinition

这一步还支持xml的方式

7.回调SpringApplicationRunListener#contextLoaded

同2

8.刷新Spring容器上下文

《Spring源码学习笔记12——总结篇IOC,Bean的生命周期,三大扩展点》这篇博客做了详细的分析

这里会进行自动装配和包路径扫描注册BeanDefinition,然后实例化单例bean

9.回调SpringApplicationRunListener#started

同2

10.callRunners

从spring容器中拿到ApplicationRunner,和CommandLineRunner调用run方法

image-20230118231725448

三丶SpringApplication,ApplicationContext,BeanFactory 三平面

我们将SpringApplication看作是SpringBoot平面,ApplicationContext看作是Spring平面,BeanFactory看作是Bean工厂平面,SpringBoot启动到触发spring容器刷新,然后触发BeanFactory实例化所有单例,非懒加载bean的流程如下

image-20230118233544314

本文转载于网络 如有侵权请联系删除

相关文章

  • 如何在Debian 10服务器上安装LAMP

    “LAMP”是开源软件的集合,通常安装在一起以允许系统部署动态应用程序。该术语是描述Linux操作系统,ApacheWeb服务器,MariaDB数据库和PHP编程的首字母缩写。另请参阅:如何在Debian10服务器上安装LEMP虽然这个“LAMP”通常涉及MySQL作为数据库管理系统,但某些Linux发行版(如Debian)使用MariaDB作为MySQL的替代品。要求如何安装Debian10(Buster)最小服务器在本文中,我们将向您展示如何使用MariaDB作为数据库管理系统在Debian10服务器上安装LAMP。在Debian10上安装ApacheWebServerApacheWeb服务器是一个开源,功能强大,可靠,安全,高度可扩展且广泛使用的HTTP服务器软件,用于托管网站。要安装Apache,请使用Debian的apt包管理器,如图所示。#aptinstallapache2复制在Debian10上安装ApacheApache安装完成后,安装程序将立即触发systemd系统和服务管理器启动Apache2服务,并使其在系统引导时自动启动。要检查Apache服务是否已启动并正常运

  • 腾讯云 CODING 上榜 2020 中国技术品牌影响力企业

    12月22日,SegmentFault思否·中国技术先锋年度评选榜单发布,腾讯云CODING凭借在DevOps领域领先的产品能力和专业的服务,荣获【中国技术品牌影响力企业】奖项。SegmentFault思否作为中国领先的新一代开发者社区,依托数百万开发者用户数据分析,及各科技企业和个人在国内技术领域的行为、影响力指标,深度考察入围企业,最终评选出30家上榜企业,和「生态发展奖」、「中国技术品牌营销奖」、「技术向善奖」、「技术文化奖」、「最佳技术服务奖」五大奖项。CODINGDevOps作为腾讯云旗下一站式研发管理协作平台,提供了代码托管、项目管理、持续集成、测试管理、持续部署、制品管理和Wiki知识库等功能服务,涵盖了软件开发从构想到交付的一切所需。一直以来,腾讯云CODING都在持续推动开发者生态的建设,以最近新发布的产品——云原生开发环境Nocalhost为例,CODING将Nocalhost全部源码开源至Github,同时遵守Apache协议并保持厂商中立,拥抱社区文化,鼓励所有开发者共同参与CODING产品乃至云原生领域的进步和成长。在未来的几年里,CODING将继续致力于为国

  • Flutter下Android Studio配置gradle的方法

    一、失败的经历:手动配置gradle下载gradle包http://gradle.org/gradle-download/MacFinder–Applications/应用程序–AndroidStudio右键显示包内容。继续打开Contents文件夹,正常情况下会有一个gradle文件夹,将下载解压之后的文件复制到这个文件夹下。如果Contents文件夹下没有gradle文件夹,创建gradle文件夹,继续后面的操作配置gradle环境路径打开终端,打开系统环境配置文件vim~/.bash_profile。将gradle的路径添加到文件中。exportGRADLE_HOME=/Applications/Android\Studio.app/Contents/gradle/gradle-6.3 exportPATH=${PATH}:${GRADLE_HOME}/bin复制文件路径就是前面存放gradle文件的路径,直接将文件拖到终端即可获取。注:获取的文件路径中在AndroidStudio.app中间加上\,即Android\Studio.app否则路径无法识别终端保存.bash_pro

  • 24-ESP8266 SDK开发基础入门篇--Android TCP客户端.控制 Wi-Fi输出PWM的占空比,调节LED亮度

    https://www.cnblogs.com/yangfengwu/p/11204436.html刚才有人说需要点鸡汤....我想想哈;我还没问关于哪方面的鸡汤呢!!!最近发现,和我干差不多行业的人开始针对我了,模仿我的也越来越多,怎么说呢!反而让我挺开心.实际上生气的是他们,因为直接影响了他们的利益,他们必须不断的去更新自己的教程,才能再次和我抗衡!我感觉我正在实现着一开始的理想,努力帮到更多的人,提高这个行业的品质和服务!教育本身就是很重要的事情!可能由于我是一路自学过来的,期间经历过太多的痛苦,然后才会深有体会,才会想着去改变一下.当然干这个行业的也有感觉着付出的太多而收益甚少的人,估计针对我的里面就有这种人,我在这里说一下,我所一直走的路线第一:能够帮到人 第二:能够获得好的人气 第三:获取利益,养活自己其实第一和第二只要你有哪一方面的优点,又肯吃苦,那么就很好走到.但是至于第三点,既要全心全意的帮助别人又要从别人那里获取利益养活自己.....其实不容易很多人只能走到第一,第二,然后走到沾一点第三的边.这个时候的人们就开始浮躁了,大部分人都会走极端,要么舍弃不干了,要么突然把

  • iOS基础开发实践:iMessage Extension浅析

    作者简介:gennyxu(徐冬成) 天天P图iOS工程师一)简介iOS10新加入的基于iMessage的应用扩展,可以丰富发送消息的内容。(分享表情、图片、文字、视频、动态消息;一起完成任务或游戏。)  简单的将发送的数据内型分为三种:贴纸Stickers;交互消息InteractiveMessages;图片,音视频,文本,链接等;两种显示模式:Compact和Expanded。 Compact模式不能访问键盘和相机,不能使用横向滑动,横向滑动操作会由系统捕获;但可以访问输入框。Expanded模式不能访问用户输入框;但是可以访问键盘、相机,并且可以使用横向滑动操作。二)iMessageExtension的分类:后面一列的Extension是在已有的App中加入iMessageExtension功能,和众多其他的Extension类似,也基本遵循其他Extension的规范。从开发角度主要分为两类:1、StickerPackApp/Extension;2、iMessageApp/Extension;创建一个StickerPackApp,实际上是创建了一个空App加上一个StickerP

  • 每个UI / UX设计师都需要知道心理学

    心理学,在用户使用APP时扮演着重要角色,对于APP的用户体验有很大的影响。通过心理学,了解到我们的设计如何被用户使用,得到反馈,从而进行调整,以便我们的APP更有效地实现用户的目标。为了帮助您理解用户的看法,我将介绍一些我认为最重要的设计原则,并配以相关案例。我们就从隔离效应开始:隔离效应VonRestorff效应预测(也称为隔离效应),当存在多个相似的物体时,与其他物体不同的物体最有可能被记住!这是所有号召性用语(CTA)与网站或APP的操作按钮醒目的主要原因!冯雷斯托夫效应例子我们希望用户能够区分简单的操作按钮和CTA,以便他们清楚地了解CTA的功能,同时在整个应用程序或网站的使用过程中记住它。“当存在多个类似物体时,与其他物体不同的物体最有可能被记住!”序列位置效应序列位置效应是用户最好记住系列中第一个和最后一个项目的倾向。从左到右,Twitter,Medium,ProductHunt这就是为什么现在大多数应用程序都将折叠菜单放在底部或顶部栏导航上,将最重要的用户操作放在右侧或左侧。在上图中,您可以看到来自流行的iOS应用程序的一些示例。每个项目都将“主页”和“配置文件”项目全

  • SAP最佳业务实践:MM–有JIT交货计划的采购(230)-1业务概览

    用途此业务情景关注于即时(JIT)采购流程。描述了在典型的重复制造环境中的内向采购处理。使用计划协议可以缩短处理时间并减少您要面对的文书工作量。一个交货计划可代替大量单独的采购订单或合同审批订单。可将库存数量降至最低。并在准时(JIT)的原则上执行生产操作。供应商要求更短的提前期。单次交货量需要减少,可在一段较长的期间内分散交货。交货计划可让供应商更高效地计划和分配自己的资源。本业务流程有JIT交货计划的采购(230)与业务流程按计划协议的销售(231)紧密结合:收货方可选用自我开票流程,并将发票信息通过EDI传输至出售方。出售方则依据此信息自动扣减未付项目。在自开票/ERS流程适用于ERS客户100020和ERS供应商300020可选:自开票流程客户通过计划协议订购物料(230)供应商参照SD计划协议创建外向发货(231)供应商根据外向发货发料(231)供应商创建一个内部开票文件在他尚未发货到客户处时(231)客户收到材料,收货,并根据发货标注过账(230)客户为收货,创建自开票文件,用MM的ERS功能(230)客户通过EDI,将开票信息传给供应商,文件中必须包括SD发货凭证号码,这

  • 什么是根号?什么是 log ?

    生日悖论是\(O(\sqrt{n})\) 随机序列LIS是\(O(\sqrt{n})\) 随机\(\pm1\)序列前缀和最大绝对值是\(O(\sqrt{n})\)证明 随机Prufer序列树树高是\(O(\sqrt{n})\) \(\suma_i=n\)的背包问题二进制分组是\(O(n\sqrt{n})\)(不带\(\log\)) 最小原根是\(O(\sqrt[4]{n})\) 随机序列前缀最大值个数是\(O(\log{n})\) 随机父亲树高与最大度数都是\(O(\log{n})\) 两维值域\(W\)凸包整点集大小至多为\(O(W^{2/3})\)

  • 【Nutch2.3基础教程】集成Nutch/Hadoop/Hbase/Solr构建搜索引擎:安装及运行【集群环境】 分类: 1_Nutch 0_jediael开发 2015-01-24 17:24 3522人阅读 评论(1) 收藏

    1、下载相关软件,并解压 版本号如下: (1)apache-nutch-2.3 (2)hadoop-1.2.1 (3)hbase-0.92.1 (4)solr-4.9.0 并解压至/opt/jediael。 若要下载最新的开发版本nutch,可以进行以下操作 svncohttps://svn.apache.org/repos/asf/nutch/branches/2.x复制 2、安装hadoop1.2.1集群环境 见http://blog.csdn.net/jediael_lu/article/details/38926477 3、安装hbase0.92.1集群环境 见http://blog.csdn.net/jediael_lu/article/details/43086641 4、Nutch的配置 (1)vi/usr/search/apache-nutch-2.3/conf/nutch-site.xml  <property> <name>storage.data.store.class</name> <v

  • 关于新版ADT创建项目时出现appcompat_v7的问题

    做Android开发的朋友最近会发现,更新ADT至22.6.0版本之后,创建新的安装项目,会出现appcompat_v7的内容。并且是创建一个新的内容就会出现。这到底是怎么回事呢?原来appcompat_v7是Google自己的一个兼容包,就是一个支持库,能让2.1以上全使用上4.0版本的界面。下面就让笔者带你慢慢走近这个问题并解决它。 参考: http://jingyan.baidu.com/article/3ea51489e04eb852e61bbaa4.html

  • 减少网站跳转时间,增强网站数据安全——HSTS 详解

    近年来随着Google、Apple、百度等公司不断推动HTTPS普及,全网HTTPS已是大势所趋。目前多数网站都已经支持HTTPS访问,但是在由HTTP转向HTTPS路程中,不少网站依然会面临很多问题。 通常用户准备访问某个网站时,不会在输入的域名前面加上http://或者https://,需要浏览器自动填充,而浏览器默认填充的都是http://,需要网站采用301/302跳转的方式,由HTTP跳转到HTTPS。  301跳转 由于301/302跳转增加了浏览器与服务器的交互,增长用户访问与等待时间,会影响用户体验,并且跳转的过程容易发生劫持,遭受第三方攻击。 当用户访问到不安全的HTTPS网址时,浏览器虽然会提示用户访问的网站不安全,但是还是允许用户在了解安全风险之后继续访问,导致用户面临数据泄密的风险。  HTTP劫持  网站不安全提醒 HSTS强制开启HTTPS保障数据安全 HSTS(HTTPStrictTransportSecurity,RFC6797),即HTTP严格安全传输,是国际互联网工程组织

  • 解决,Incorrect table definition; there can be only one auto column and it must be defined as a key

    今天在迁移项目时,操作数据库报错: Incorrecttabledefinition;therecanbeonlyoneautocolumnanditmustbedefinedasakey 我用的是NavicatPremium,而检测表中其他字段发现,并没有另一个设为自增的字段,很是费解,最后在stackoverflow找到这样的答案:   意思是:设为自增的字段必须是主键,而我用的是客户端,表是批量从SQLServer复制到MySQL的,导致最后MySQL表中主键丢失,设置id为主键并设为自增后,保存成功,问题解决。

  • oracle内存分析

    oracle时间内存=SGA+PGA SGA(SystemGlobalArea):由所有服务进程和后台进程共享; PGA(ProgramGlobalArea):由每个服务进程、后台进程专有;每个进程都有一个PGA。 二、SGA 包含实例的数据和控制信息,包含如下内存结构: 1)Databasebuffercache:缓存了从磁盘上检索的数据块。 2)Redologbuffer:缓存了写到磁盘之前的重做信息。 3)Sharedpool:缓存了各用户间可共享的各种结构。 4)Largepool:一个可选的区域,用来缓存大的I/O请求,以支持并行查询、共享服务器模式以及某些备份操作。 5)Javapool:保存java虚拟机中特定会话的数据与java代码。 6)Streamspool:由Oraclestreams使用。 7)Keepbuffercache:保存buffercache中存储的数据,使其尽时间可能长。 8)Recyclebuffercache:保存buffercache中即将过期的数据。 9)nKblocksizebuffer:为与数据库默认数据块大小不同的数据块提供缓存。用来支

  • Win10 这台计算机中已经安装了 .NET Framework 4.6.2 或版本更高的更新

    win10安装.NETFramework4.6.2 Win10系统自带的.netframework版本为4.7,自己安装.NETFramework4.6.2时会提示:这台计算机中已经安装了.NETFramework4.6.2或版本更高的更新。 解决方法 下载安装.netframework的开发版或者说开发包。开发版地址 点击DeveloperPack 进行下载,下载后正常安装即可,装完后重启即可

  • tensorrt int8量化原理几点问题记录

    1.重新编码后是如何运算得到最终结果的? (1)如何用int8表示float32的计算?   其实就是多了一个放大倍数的问题,举个例子:比如原来float32的计算为:0.1*0.2+0.3*0.4=0.14,那么使用int8计算:1*2+3*4=14,相当于原来的数值都取10倍放大倍数(int8标定也就是标定这个放大倍数),那么由于乘法的原因,最后的结果相当于放大了100倍.这样就能使用Int8来取代float32的计算. (2)怎么解决偏置问题及溢出问题?   假设我们的网络是卷积后面紧跟着偏置,例如:原来float32的计算为:0.1*0.2+0.1=0.12,这时候如果采取和上面一样的策略,那么就会得到:1*2+1=3,再缩小100倍得到结果:0.03,问题出在偏置放大了10倍,前面是个乘法运算,相当于放大了100倍,也就是说带偏置的层要特殊处理一下?   另一个问题:用Int8计算卷积是很容易溢出了,比如:56*45这个值明显大于INT8_MAX==127,这时候怎么处理? nvdia官方的tensorrt-int8文档(http://on-demand.gputechcon

  • EF6 SQL Logging – Part 3: Interception building blocks | One Unicorn

    Inparts1and2ofthisserieswelookedathowtouseDbContext.Database.LogtologtheSQLgeneratedbyEF.Butthiscodeisactuallyarelativelythinfaçadeoversomelow-levelbuildingblocksforinterceptioningeneraland,inthiscase,DbCommandinterceptioninparticular.InterceptioninterfacesTheinterceptioncodeisbuiltaroundtheconceptofinterceptioninterfaces.TheseinterfacesinheritfromIDbInterceptoranddefinemethodsthatarecalledwhenEFperformssomeaction.Theintentistohaveoneinterfacepertypeofobjectbeingintercepted.Forexample,theIDbComm

  • [iOS]创建界面方法的讨论

    以前在入门的时候,找的入门书籍上编写的demo都是基于Storyboards拖界面的。后来接触公司项目,发现界面都是用纯代码去写复杂的autoLayout的。再然后,领导给我发了个Masonry库去看,依然是手写代码布局界面,但效率高了不少。工作一段时间,看了很多博客,也看了一些书,发现用纯代码写界面的很少,于是就在Google上搜Storyboards有什么好处,最后发现了一篇非常好的文章。在此提炼文章的一些观点,同时表达一下自己的观点。 文章链接:iOSUserInterfaces:Storyboardsvs.NIBsvs.CustomCode 文章介绍了三种构建界面的方法,并对不同方法分别讨论了优缺点。 其实对于这几种方法,没有最好,只有最适合。 总结下来就是Storyboards是一个容易观察并且使用简单的iOSUI设计工具。它也消除了固定的创建控件的模板代码,但导致了很严重的灵活性的缺失。NIBs对于singleview来说提供了很大灵活性,但没有视觉流(个人猜测是viewcontroller的切换)。灵活性最大的方案就是纯代码布局,但纯代码并不是那么直观,也没有那么容易。

  • 王者荣耀 嫦娥 同人 3D渲染 壁纸 家居服 减布料

    1080P版关注公众号或者P站免费获取 4K版 4K版下载

  • Java在Eclipse中调试无法获取JDK源码变量的解决办法

    1.问题描述  在Eclipse中调试jdk源码时,变量无法显示并提示说“keycannotberesolvedtoavariable”。    这是因为在JDK中,sun对rt.jar中的类编译时,去除了调试信息。 2.解决方法   1.在D盘新建文件夹【jdk】,然后在文件夹里面分别创建两个文件夹【 jdk_src】(源码)和【 jdk_debug】(编译文件)。     2.从%JAVA_HOME%路径下找到【src.zip】源码源码压缩包,解压至D:/jdk/jdk_src目录中,并只保留【java,javax,org】三个文件夹。     3.从%JAVA_HOME%\jre\lib找到【rt.jar】,将它拷贝到D:/jdk文件夹。     4.打开DOS命令窗口,用命令cd命令进入D:/jdk文件夹,然后执行命令【 dir/B/S/X.\jdk_src\*.java>.

  • Hyperledger Fabric——balance transfer(五)执行交易

    链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的。 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channelName/chaincodes/:chaincodeName',asyncfunction(req,res){ varpeers=req.body.peers; varchaincodeName=req.params.chaincodeName; varchannelName=req.params.channelName; varfcn=req.body.fcn; varargs=req.body.args; //此处省略了参数校验 letmessage=awaitinvoke.invokeChaincode(peers,channelName,chaincodeName,fcn,args,req.username,req.orgname); res.send(message); });复制 2.接下来找到 varinvokeChaincode=asyncf

  • github

    metapath2vec相关 xiaohan2012 有计划的git用户,每个月更新论文阅读情况(值得经常去看) GraphalgorithmsforHetNets #56 如有疑问请联系我,写的不对的地方请联系我进行更改,感谢~QQ:1968380831

相关推荐

推荐阅读