Spring Boot基础(五)SpringBoot启动流程
SpringBoot从主类的main方法中的run方法进入,跳转到Application类中的ConfigurableApplicationContext方法,new了一个SpringApplication对象,并且执行了它的run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); }
当new一个SprngApplication对象时,调用了SpringApplication的构造方法:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; //判断是否有主类 Assert.notNull(primarySources, "PrimarySources must not be null"); //参数放入一个set this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); //判断是否为web环境 this.webApplicationType = WebApplicationType.deduceFromClasspath(); this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class)); //从配置文件中获取Initializers和Listeners两种监听器的名字 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
执行完构造后,对象初始化完毕,监听器已获取,开始真正执行run方法
public ConfigurableApplicationContext run(String... args) { //计时 long startTime = System.nanoTime(); DefaultBootstrapContext bootstrapContext = createBootstrapContext(); ConfigurableApplicationContext context = null; configureHeadlessProperty(); //获取获取所有的RunListener(包括自己定义的) SpringApplicationRunListeners listeners = getRunListeners(args); //调用所有Listeners的Startting方法 listeners.starting(bootstrapContext, this.mainApplicationClass); try { //准备启动,封装参数对象 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //准备环境, ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); //开始创建context(即IoC容器) context = createApplicationContext(); context.setApplicationStartup(this.applicationStartup); //传入listeners,Initializer被初始化。Ioc已创建完毕,未加载Bean prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); //刷新context,在配置中寻找并创建Bean refreshContext(context); afterRefresh(context, applicationArguments); //计时停止 Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup); } //执行后,项目启动成功 listeners.started(context, timeTakenToStartup); //回调Runner,即ApplicationRunne 和CommandLineRunner被调用 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, listeners); throw new IllegalStateException(ex); } try { Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime); listeners.ready(context, timeTakenToReady); } catch (Throwable ex) { handleRunFailure(context, ex, null); throw new IllegalStateException(ex); } //返回IoC容器 return context; }
Startting方法,旧版是用for-each方法实现:
void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainApplicationClass) { doWithListeners("spring.boot.application.starting", (listener) -> listener.starting(bootstrapContext), (step) -> { if (mainApplicationClass != null) { step.tag("mainApplicationClass", mainApplicationClass.getName()); } }); }
本文来自博客园,作者:我永远喜欢石原里美,转载请注明原文链接:https://www.cnblogs.com/yuan-zhou/p/15824191.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY