当前位置: 首页 > article >正文

Springboot3 自动装配之核心文件:imports文件

注:本文以spring-boot v3.4.1源码为基础,梳理spring-boot应用启动流程、分析自动装配的原理

如果对spring-boot2自动装配有兴趣,可以看看我另一篇文章:
Springboot2 自动装配之spring-autoconfigure-metadata.properties和spring.factories(SPI机制核心)

启动入口

以下是源码里一段应用启动单元测试代码:

package org.springframework.boot.test.autoconfigure;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Tests for {@link ConditionReportApplicationContextFailureProcessor}.
 *
 * @author Phillip Webb
 * @author Scott Frederick
 * @deprecated since 3.2.11 for removal in 3.6.0
 */
@ExtendWith(OutputCaptureExtension.class)
@Deprecated(since = "3.2.11", forRemoval = true)
@SuppressWarnings("removal")
class ConditionReportApplicationContextFailureProcessorTests {

	@Test
	void loadFailureShouldPrintReport(CapturedOutput output) {
		SpringApplication application = new SpringApplication(TestConfig.class);
		application.setWebApplicationType(WebApplicationType.NONE);
		ConfigurableApplicationContext applicationContext = application.run();
		ConditionReportApplicationContextFailureProcessor processor = new ConditionReportApplicationContextFailureProcessor();
		processor.processLoadFailure(applicationContext, new IllegalStateException());
		assertThat(output).contains("CONDITIONS EVALUATION REPORT")
			.contains("Positive matches")
			.contains("Negative matches");
	}

	@Configuration(proxyBeanMethods = false)
	@ImportAutoConfiguration(JacksonAutoConfiguration.class)
	static class TestConfig {

	}
}

spring-boot3应用启动入口是SpringApplication的构造方法,这个构造方法里做了一些初始化,比较重要。如下:

	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		// @A
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		// @B
		this.properties.setWebApplicationType(WebApplicationType.deduceFromClasspath());
		// @C
		this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

@A:标签当前应用的启动主类,也就是我们平常写的xxxApplication类
@B:在类路径下查找是否有 :

  • private static final String WEBMVC_INDICATOR_CLASS = “org.springframework.web.servlet.DispatcherServlet”;
  • private static final String WEBFLUX_INDICATOR_CLASS = “org.springframework.web.reactive.DispatcherHandler”;
  • private static final String JERSEY_INDICATOR_CLASS = “org.glassfish.jersey.servlet.ServletContainer”;
    中的一个,标记当前web应用类型;web应用类型有:REACTIVE SERVLET NONE

@C:从类路径中可见的 spring.factories 文件中获取配置的BootstrapRegistryInitializer.class、ApplicationContextInitializer.class、ApplicationListener.class并缓存

启动核心方法 public ConfigurableApplicationContext run(String… args){}
public ConfigurableApplicationContext run(String... args) {
		Startup startup = Startup.create();
		if (this.properties.isRegisterShutdownHook()) {
			SpringApplication.shutdownHook.enableShutdownHookAddition();
		}
        // @A
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		configureHeadlessProperty();
		// @B
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			context.setApplicationStartup(this.applicationStartup);
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			startup.started();
			if (this.properties.isLogStartupInfo()) {
				new StartupInfoLogger(this.mainApplicationClass, environment).logStarted(getApplicationLog(), startup);
			}
			listeners.started(context, startup.timeTakenToStarted());
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			throw handleRunFailure(context, ex, listeners);
		}
		try {
			if (context.isRunning()) {
				listeners.ready(context, startup.ready());
			}
		}
		catch (Throwable ex) {
			throw handleRunFailure(context, ex, null);
		}
		return context;
	}

@A:创建DefaultBootstrapContext对象,逐个执行前面缓存中bootstrapRegistryInitializers的initialize方法
@B:从类路径META-INF/spring.factories配置文件中获取SpringApplicationRunListener配置的类(框架默认提供了EventPublishingRunListener)封装成SpringApplicationRunListeners,然后执行SpringApplicationRunListeners的starting方法,最终调用的是EventPublishingRunListener等配置类的starting方法

todo~~


http://www.kler.cn/a/514952.html

相关文章:

  • YOLOv8改进,YOLOv8检测头融合DSConv(动态蛇形卷积),并添加小目标检测层(四头检测),适合目标检测、分割等
  • OneData体系架构详解
  • 正则表达式的艺术:轻松驾驭 Python 的 re 库
  • Spring WebFlux 和 Spring MVC 的主要区别是什么?
  • 2025年入职/转行网络安全,该如何规划?网络安全职业规划
  • AI Agent:AutoGPT的使用方法
  • Spring 依赖注入详解:创建 Bean 和注入依赖是一回事吗?
  • 【JAVA】BOSS系统发版艺术:构建高效、优雅的微服务部署策略
  • mq_open创建队列失败
  • Flink在流处理中,为什么还会有窗口的概念呢
  • 全球化趋势与中资企业出海背景
  • Spring MVC和Spring WebFlux的区别
  • Linux系统总结
  • 前沿技术对比:大模型技术为什么发展远快于区块链技术,中英对照解释
  • 2.6 createCmd中的builder建造者设计模式
  • 【Maui】提示消息的扩展
  • HTB:Heist[WriteUP]
  • HTML5 History API
  • 校园网上店铺的设计与实现(代码+数据库+LW)
  • enum EPOLL_EVENTS详解
  • 本地仓库管理之分支间的操作
  • MongoDB 创建集合
  • AIGC视频生成模型:慕尼黑大学、NVIDIA等的Video LDMs模型
  • 大语言模型之prompt工程
  • pytest执行报错:found no collectors
  • 单片机基础模块学习——定时器