SpringBoot启动流程-new SpringApplication

本文详细解析了Spring Boot启动过程中的关键步骤,包括通过spring.factories文件获取ApplicationContextInitializer和ApplicationListener,以及如何通过堆栈信息推断出主类。

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

new SpringApplication()主要过程

根据spring.factories配置文件,找到配置的应用上下文类(#Application Context Initializers)和监听器类(#Application Listeners),并根据反射机制创建相应对象,最后推断出包含main方法的主类。

1.推断应用web类型

默认是servlet

 

2.设置ApplicationContextInitializer和ApplicationListener

总结:通过读取spring.factories文件获取全部类全限定名--->根据Initializer和ApplicationListener获取对应类全限定名--->根据类全限定名使用反射方法创建对应的对象--->将对象赋值给SpringApplication对象的initializers属性。

this.initializers.addAll(initializers);

 

6个ApplicationContextInitializer

//核心方法
setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));
Class.forName(url);
class.getConstructor(class...).newInstance(param..) 

(1)获取类全限定名

首先读取所有jar包中的spring.factories文件中的类全限定名,然后利用key、value存储到map中。再使用key = org.springframework.context.ApplicationContextInitializer,从map中获取对应的value值,获取到6个Initializer。

[org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer, 
org.springframework.boot.context.ContextIdApplicationContextInitializer, 
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
 org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer, 
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer, 
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener]

(2)反射方式创建对象

forName(elementClassName, classLoader);//利用classloader和类全限定名获取class对象
instanceClass.getDeclaredConstructor(parameterTypes);//获取类的构造器
ctor.newInstance(args);//利用构造器创建对象
 

13个ApplicationListener

设置思路和上述Initializer一样。

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.listeners.addAll(listeners);//将获取到的listener对象设置到SpringApplication对象的属性中
[org.springframework.cloud.bootstrap.BootstrapApplicationListener, 
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener, 
org.springframework.cloud.context.restart.RestartListener, 
org.springframework.boot.ClearCachesApplicationListener, 
org.springframework.boot.builder.ParentContextCloserApplicationListener, 
org.springframework.boot.context.FileEncodingApplicationListener, 
org.springframework.boot.context.config.AnsiOutputApplicationListener, 
org.springframework.boot.context.config.ConfigFileApplicationListener, 
org.springframework.boot.context.config.DelegatingApplicationListener, 
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener, 
org.springframework.boot.context.logging.LoggingApplicationListener, 
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener, 
org.springframework.boot.autoconfigure.BackgroundPreinitializer]

3.推断出当前主类

总结:通过RuntimeException().getStackTrace()获取运行时堆栈信息,遍历堆栈元素方法名是否为“main”,利用Class.forName(className)推断出运行主类。

//根据栈中的方法名是否包含main,推断当前main方法所在的类
this.mainApplicationClass = deduceMainApplicationClass();

//deduceMainApplicationClass()核心代码
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
			for (StackTraceElement stackTraceElement : stackTrace) {
				if ("main".equals(stackTraceElement.getMethodName())) {
					return Class.forName(stackTraceElement.getClassName());
				}
			}

 

### Spring Boot 和 JavaFX 集成与打包解决方案 在现代开发环境中,将 JavaFX 与 Spring Boot 结合可以充分利用两者的优势:Spring Boot 提供强大的微服务框架支持,而 JavaFX 则提供丰富的图形界面功能。以下是关于如何实现两者的集成以及正确打包的方法。 #### 1. 添加依赖项 为了使 Spring Boot 支持 JavaFX 的运行环境,需要引入必要的 Maven 或 Gradle 依赖项。以下是一个典型的 Maven `pom.xml` 文件配置: ```xml <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- JavaFX SDK --> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>17.0.1</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>17.0.1</version> </dependency> </dependencies> ``` 上述代码片段展示了如何通过 Maven 来管理 JavaFX 控件和 FXML 解析器的相关库[^1]。 #### 2. 创建启动类 由于 JavaFX 应用程序基于 `Application.launch()` 方法初始化 GUI 线程,因此需要自定义一个继承于 `javafx.application.Application` 并嵌套调用 Spring 上下文的入口点。下面展示了一个简单的例子: ```java import javafx.application.Application; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; public class MainApp extends Application { private ConfigurableApplicationContext springContext; @Override public void init() throws Exception { // 启动 Spring Boot 应用上下文 springContext = SpringApplication.run(YourBootApplication.class); } @Override public void start(Stage primaryStage) throws Exception { Parent root = springContext.getBean(MainController.class).getView(); Scene scene = new Scene(root); primaryStage.setTitle("Spring Boot + JavaFX"); primaryStage.setScene(scene); primaryStage.show(); } @Override public void stop() throws Exception { super.stop(); springContext.close(); // 关闭 Spring 上下文 } } ``` 此部分实现了 JavaFX 生命周期方法中的 Spring 初始化逻辑,并确保资源能够被正常释放[^2]。 #### 3. 打包方案 对于最终部署而言,传统的 JAR 文件可能无法满足需求,因为它们不包含本地平台特定的二进制文件(如 DLL、SO)。推荐使用工具如 **JPackage** 或者第三方构建插件来完成跨平台分发的任务。 ##### 使用 JPackage 工具 从 JDK 14 开始提供了官方命令行实用程序——JPackage,它允许开发者轻松创建可执行安装包。基本流程如下所示: ```bash jpackage --type app-image \ --input target/your-app-name.jar \ --main-jar your-main-class-file.jar \ --dest output_directory/ ``` 以上脚本会生成适用于目标操作系统的独立应用程序镜像目录结构[^3]。 #### 总结 通过合理设置项目架构并利用现代化技术手段解决传统难题,可以使复杂的桌面应用更加易于维护和发展。同时也要注意版本兼容性和性能优化等问题,在实际生产环境下需进一步测试验证其稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值