第 4 节 基于 main 方法启动 SpringBoot 进程

本文深入探讨了Java程序如何通过静态main方法启动,解析了main方法的定义规范及其与JVM进程的关系。同时,分析了SpringBoot项目如何基于main方法启动独立的JVM进程,简化部署流程,无需依赖外部容器。SpringApplication的run方法在启动过程中扮演关键角色,负责Spring容器的初始化和应用的运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 静态 main 方法与 JVM 进程的关系

​ 在讲解 SpringBoot 项目的启动和运行之前,首先分析一下基于静态 main 方法启动运行 Java 类的相关知识,以便读者能够更好理解基于 SpringBoot 框架搭建的项目的启动和运行方式。

1.1 基于静态 main 方法执行 Java 类

​ Java 类的静态 main 方法是每一个 Java 开发人员都再熟悉不过的一个方法,在进行 Java 应用程序开发,特别是 Java SE 应用程序开发时,一般都会在 Java 类定义一个静态 main 方法来作为该类的执行入口。

​ 具体为在运行该 Java 类时,main 方法会被 JVM 调用,然后执行 main 方法内部的每一行代码,执行完毕之后,程序退出。如下为静态 main 方法的定义:

public class MainDemo {
    // 类执行入口
    public static void main(String[] args) {
        // 自定义需要执行的代码
    }
}

拓展知识:

Java 语言由于底层是基于 c 语言实现的,故在类的运行方面也仿照了 c 语言的习惯,使用一个名为 main 的方法来作为类的执行入口。

不过 Java 语言在具体设计方面结合了 Java 语言的相关特性,即 main 方法需要使用 static 关键字修饰来成为 Java 的类方法,从而实现了无需创建类的对象实例即可调用该 main 方法。

1.2 静态 main 方法的定义

​ 该静态 main 方法的返回类型为 void,参数为 String 字符串数组 args,该数组代表该类的多个运行时参数,具体可以通过以下方式来传递:

java DemoMain 1 2 3

其中 java 为 Java 语言提供的执行类的命令,DemoMain 是以上类的类名,注意该类对应的 class 文件需要在类路径下,1,2,3 就是以上的 args 字符串数组的内容,即 args[0] = 1,args[1] = 2,args[2] = 3。

拓展知识:

注意 main 方法作为类的执行入口的以上两个条件,即方法返回类型为 void,方法参数为 String 字符串数组是必须的,否则 Java 类在运行时无法将该方法作为执行入口。例如,如果返回类型为 int,或者方法参数为空,则该 main 方法只是一个普通的静态方法,而不是该类的执行入口。

以上两个条件都是 Java 语言自身的规范,只有符合规范才能被 JVM 识别和执行。

​ 除此之外, main 方法需要使用 static 关键字修饰来成为静态方法的原因是:静态方法也称为类方法,即 main 方法是类对象的方法,而不是通过 new 关键字创建的类的对象实例的成员方法。

​ 由 JVM 类加载的相关知识可知,JVM 在运行过程中,当需要使用某个类的时候,如访问该类的静态属性时(或者类的静态方法,或者创建该类的对象实例),需要将该类的 class 文件的二进制数据加载到 JVM 的运行时数据区的方法区中,并且会创建对应的类型为 java.lang.Class 的类对象。之后就可以使用该类对象来访问该类的相关信息,如类的静态属性等。

​ 所以当通过 java 命令来执行某个类时,首先会创建一个 JVM 进程,然后加载该类的二进制数据到 JVM 的方法区并创建类型为 java.lang.Class 的类对象。接着在该 JVM 进程的主线程中会通过该类对象来调用该类的 main 方法,从而完成类的执行。当 执行完 main 方法的所有代码,则方法调用结束,JVM 进程退出。

tips:不过如果在 main 方法内,存在让主线程阻塞等待的方法调用的话,则 JVM 进程会继续保持运行状态而不会退出,这也是 SpringBoot 框架基于 main 方法来启动 JVM 进程并保持该进程运行而不退出的实现原理。

2 SpringBoot项目的启动与运行

​ SpringBoot 框架的一个核心设计就是基于 main 方法来独立启动一个 JVM 进程来运行应用,而不需要将应用打 包为 war 包并部署到 Tomcat 去运行。这种设计简化了基于 SpringBoot 搭建的项目的部署和运行流程,使得 Java 企业级应用回归了最原始、最简单、但又是最高效的运行模式。

​ 所以基于 SpringBoot 框架搭建项目时,会在应用代码目录 java 的顶层包路径下包含一个名称类似于 XXXApplication 的项目启动类,其中 XXX 是项目名称。如下是在上一小节介绍的 demo 项目中,由 SpringBoot 框架自动创建的的项目启动类 DemoApplication 的源码:

package com.yzxie.study.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }

}

​ 由以上源码实现可知,在 DemoApplication 类的执行入口方法 main 中只包含了一行代码,即调用由 SpringBoot 框架提供的 SpringApplication 类的静态方法 run 来完成 SpringBoot 框架的启动与运行。

拓展知识:

SpringApplication 的静态 run 方法的核心工作包括:在内部完成 Spring IOC 容器的加载和相关 bean 对象的创建,完成 Servlet 引擎的加载与在指定端口监听客户端的连接请求,使得该 JVM 进程的主线程阻塞不退出,保持运行状态,从而实现与传统的、将项目打 war 包部署到 Tomcat 去运行一样的效果。关于 SpringApplication 类的相关用法与设计原理的更多知识在后续章节详细分析。

​ 由以上 1.1 部分的分析可知,当需要启动和运行项目时,可以使用 java 命令来启动和运行项目启动类,如 demo 项目的 DemoApplicatiion 。

​ 不过与运行单个 Java 类不一样,在命令行使用 java 命令启动项目时,首先需要将整个项目打成一个 jar 包,然后将该 jar 包添加到系统的类路径,或者在 java 命令中指定该 jar 包所在的类路径,最后在 java 命令中指定需要执行的 Java 类名,如 DemoApplication,完成启动和执行该类。

tips:Java 命令执行 Java 类的工作原理为首先创建一个 JVM 进程,然后在主线程中调用 main 方法来完成类的执行。其中将项目打成 jar 包并使用 java 命令来在命令行启动和运行项目是 Java 企业级项目在 Linux 服务器部署的常用方式。

3 总结

​ 在本小节我们首先介绍了 Java 语言最原始的基于静态 main 方法来执行 Java 类的相关用法和工作原理,以及分析了 main 方法定义的相关规范。具体为 main 方法要符合是静态方法,方法返回值为 void,方法参数为 String 数组这三个条件,只有这样才能被 JVM 进程识别为执行入口方法并进行调用。

​ 其次我们分析了 SpringBoot 应用的启动运行方式,即基于 SpringBoot 搭建的项目回归了基于 main 方法启动运行的方式,从而实现了以独立 JVM 进程来启动和运行项目,而不需要依赖额外部署的 Tomcat,这极大简化了 Spring 应用的部署和运行流程。

### 配置同一服务器上的Spring Boot和Vue项目以实现同时启动 为了在同一台服务器上顺利运行Spring Boot和Vue应用程序,通常采用前后端分离的方式部署。对于前端部分,即Vue构建后的`dist`目录下的静态文件,可以通过多种方式处理: - 将这些静态文件放置于Web服务器(如Nginx或IIS)的根目录下[^3]。 - 或者更简单地,将它们放入Spring Boot项目的静态资源路径内,比如`src/main/resources/static`中[^1]。 针对后端服务——Spring Boot应用,则需确保其能够独立运行,并通过API接口的形式向前端提供数据支持。当考虑二者的同时启动时,一种常见的做法是在打包阶段就做好准备,使得最终产物可以直接被服务器识别并执行。 #### 使用Maven构建工具来管理Spring Boot项目 在POM.xml文件里指定好必要的配置项之后,可通过如下命令完编译与打包操作: ```bash mvn clean package -DskipTests=true ``` 这将会生一个可执行的JAR包,在该过程中也包含了对前端资源的集工作。如果选择了让Vue的应用作为静态资源嵌入到Spring Boot内部的话,那么只需保证每次更新前端代码后重新执行上述命令即可保持同步。 #### 设置自动启动机制 为了让两个程序能随着操作系统开机而自启,可以利用Linux系统的Systemd服务定义或是Windows的任务计划功能创建相应的脚本。特别是对于基于Java开发的Spring Boot来说,还可以借助内置的功能组件CommandLineRunner或ApplicationRunner来自定义一些初始化逻辑,例如设置监听器用于监控特定事件的发生,从而间接达到控制其他进程的目的[^2]。 另外值得注意的是,虽然理论上允许把前后两端都放在同一个进程中一起发布,但从架构设计角度出发,建议还是分开维护各自的服务实例更为合理。这样做不仅有利于团队协作分工明确,而且便于后期运维管理和性能优化调整。 最后关于网络通信方面,考虑到WebSocket相较于Server-Sent Events(SSE)具有更好的跨平台性和稳定性表现,因此推荐优先选用前者来进行实时消息推送等功能模块的设计实现[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值