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

计算机做网站开发需要什么证书google chrome谷歌浏览器

计算机做网站开发需要什么证书,google chrome谷歌浏览器,免费的wordpress模板下载,网站建设诚信服务Spring Boot 启动流程深度解析:从源码到实践 Spring Boot 作为 Java 开发的主流框架,其 “约定大于配置” 的理念极大提升了开发效率。本文将从源码层面深入解析 Spring Boot 的启动流程,并通过代码示例展示其工作机制。 一、Spring Boot 启…

Spring Boot 启动流程深度解析:从源码到实践

Spring Boot 作为 Java 开发的主流框架,其 “约定大于配置” 的理念极大提升了开发效率。本文将从源码层面深入解析 Spring Boot 的启动流程,并通过代码示例展示其工作机制。

一、Spring Boot 启动的入口点

Spring Boot 应用的启动通常从一个包含main方法的类开始:

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

@SpringBootApplication是一个组合注解,包含:

  • @SpringBootConfiguration:声明这是一个配置类
  • @EnableAutoConfiguration:启用自动装配机制
  • @ComponentScan:启用组件扫描

SpringApplication.run()是启动的核心方法,下面我们深入分析其执行流程。

二、SpringApplication 的初始化

当调用SpringApplication.run()时,首先会创建SpringApplication实例:

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class<?>[] { primarySource }, args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args);
}

SpringApplication的构造函数会执行一系列初始化操作:

public SpringApplication(Class<?>... primarySources) {this(null, primarySources);
}@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 1. 判断应用类型(REACTIVE, SERVLET, NONE)this.webApplicationType = WebApplicationType.deduceFromClasspath();// 2. 设置ApplicationContextInitializersetInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 3. 设置ApplicationListenersetListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 4. 推断主应用类(包含main方法的类)this.mainApplicationClass = deduceMainApplicationClass();
}

关键步骤解析:

  1. 应用类型推断:根据类路径中的类推断应用类型(WebFlux、Servlet 或普通应用)
  2. 初始化器加载:从META-INF/spring.factories加载ApplicationContextInitializer
  3. 监听器加载:从META-INF/spring.factories加载ApplicationListener
  4. 主应用类推断:通过栈轨迹找到包含 main 方法的类

三、SpringApplication.run () 方法解析

run()方法是 Spring Boot 启动的核心逻辑:

public ConfigurableApplicationContext run(String... args) {long startTime = System.nanoTime();DefaultBootstrapContext bootstrapContext = createBootstrapContext();ConfigurableApplicationContext context = null;configureHeadlessProperty();// 1. 获取并启动所有SpringApplicationRunListenerSpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 2. 准备环境ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);configureIgnoreBeanInfo(environment);// 3. 打印BannerBanner printedBanner = printBanner(environment);// 4. 创建ApplicationContextcontext = createApplicationContext();context.setApplicationStartup(this.applicationStartup);// 5. 准备上下文prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 6. 刷新上下文refreshContext(context);// 7. 刷新后的处理afterRefresh(context, applicationArguments);// 8. 计时结束Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}// 9. 发布应用启动完成事件listeners.started(context, timeTakenToStartup);// 10. 调用所有RunnerscallRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {// 11. 发布应用就绪事件Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}catch (Throwable ex) {if (context != null) {context.close();throw new IllegalStateException("Error handling failed", ex);}throw new IllegalStateException(ex);}return context;
}

四、关键步骤详解

1. 启动监听器(SpringApplicationRunListeners)

Spring Boot 通过事件机制在启动的不同阶段发布事件,允许开发者介入:

private SpringApplicationRunListeners getRunListeners(String[] args) {Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };return new SpringApplicationRunListeners(logger,getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),this.applicationStartup);
}

核心监听器包括EventPublishingRunListener,它会发布一系列事件:

  • ApplicationStartingEvent
  • ApplicationEnvironmentPreparedEvent
  • ApplicationContextInitializedEvent
  • ApplicationPreparedEvent
  • ApplicationStartedEvent
  • ApplicationReadyEvent
2. 环境准备(prepareEnvironment)

环境准备包括创建并配置ConfigurableEnvironment,加载属性源和配置文件:

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,DefaultBootstrapContext bootstrapContext,ApplicationArguments applicationArguments) {// 创建环境(Web或非Web)ConfigurableEnvironment environment = getOrCreateEnvironment();// 配置环境configureEnvironment(environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach(environment);// 发布环境准备事件listeners.environmentPrepared(bootstrapContext, environment);bindToSpringApplication(environment);if (!this.isCustomEnvironment) {environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,deduceEnvironmentClass());}ConfigurationPropertySources.attach(environment);return environment;
}
3. 创建应用上下文(createApplicationContext)

根据应用类型创建不同的ApplicationContext

protected ConfigurableApplicationContext createApplicationContext() {Class<?> contextClass = this.applicationContextClass;if (contextClass == null) {try {// 根据应用类型选择上下文类switch (this.webApplicationType) {case SERVLET:contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;case REACTIVE:contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);break;default:contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);}}catch (ClassNotFoundException ex) {throw new IllegalStateException("Unable to create a default ApplicationContext, please specify an ApplicationContextClass", ex);}}return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
4. 准备应用上下文(prepareContext)

对创建好的上下文进行初始化,包括设置环境、加载源、应用初始化器等:

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {// 设置环境context.setEnvironment(environment);// 应用上下文后置处理器postProcessApplicationContext(context);// 应用初始化器applyInitializers(context);// 发布上下文初始化事件listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// 添加资源加载器和主应用类ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}// 设置懒加载if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}// 加载源(主配置类)Set<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");load(context, sources.toArray(new Object[0]));// 发布上下文加载完成事件listeners.contextLoaded(context);
}
5. 刷新应用上下文(refreshContext)

调用AbstractApplicationContext.refresh()方法,这是 Spring 框架的核心逻辑,包括:

  • BeanFactory 的创建与初始化
  • BeanDefinition 的加载
  • Bean 的创建与依赖注入
  • 自动装配的处理
  • 事件发布器的初始化
  • 嵌入式 Servlet 容器的启动(如果是 Web 应用)
private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {try {context.registerShutdownHook();}catch (AccessControlException ex) {// Not allowed in some environments.}}refresh(context);
}protected void refresh(ConfigurableApplicationContext context) {context.refresh();
}
6. 调用应用 Runner(callRunners)

启动完成后,调用所有实现了ApplicationRunnerCommandLineRunner的 Bean:

private void callRunners(ApplicationContext context, ApplicationArguments args) {List<Object> runners = new ArrayList<>();// 添加所有ApplicationRunnerrunners.addAll(context.getBeansOfType(ApplicationRunner.class).values());// 添加所有CommandLineRunnerrunners.addAll(context.getBeansOfType(CommandLineRunner.class).values());// 排序AnnotationAwareOrderComparator.sort(runners);// 调用for (Object runner : new LinkedHashSet<>(runners)) {if (runner instanceof ApplicationRunner) {callRunner((ApplicationRunner) runner, args);}if (runner instanceof CommandLineRunner) {callRunner((CommandLineRunner) runner, args);}}
}

五、自定义启动流程

开发者可以通过以下方式自定义启动流程:

1. 添加 ApplicationContextInitializer
public class CustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {// 在上下文刷新前执行自定义逻辑System.out.println("Custom initializer called");}
}

注册方式:

@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication app = new SpringApplication(MyApplication.class);app.addInitializers(new CustomApplicationContextInitializer());app.run(args);}
}
2. 添加 ApplicationListener
public class CustomApplicationListener implements ApplicationListener<ApplicationStartedEvent> {@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {// 应用启动后执行System.out.println("Application started!");}
}

注册方式:

@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication app = new SpringApplication(MyApplication.class);app.addListeners(new CustomApplicationListener());app.run(args);}
}
3. 实现 CommandLineRunner 或 ApplicationRunner
@Component
public class CustomCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("CommandLineRunner executed with args: " + Arrays.toString(args));}
}

六、启动流程总结

Spring Boot 的启动流程可以概括为以下关键步骤:

  1. 初始化 SpringApplication
    • 推断应用类型
    • 加载初始化器和监听器
    • 确定主应用类
  2. 执行 run () 方法
    • 发布启动事件
    • 准备环境(加载配置属性)
    • 创建应用上下文
    • 准备上下文(设置环境、加载源)
    • 刷新上下文(核心 Spring 容器初始化)
    • 调用应用 Runner
    • 发布就绪事件
  3. 核心机制
    • 事件机制:通过ApplicationEventApplicationListener实现
    • 自动装配:在上下文刷新阶段通过@EnableAutoConfiguration触发
    • 条件注解:控制配置类的加载条件

理解 Spring Boot 的启动流程有助于开发者更好地调试应用、自定义启动行为,以及解决启动过程中遇到的问题。通过扩展点(Initializers、Listeners、Runners),开发者可以在不修改核心代码的情况下介入启动流程,实现各种定制需求。

http://www.dtcms.com/wzjs/310608.html

相关文章:

  • 请问聊城做网站seo服务优化
  • 软件下载大全网站seo怎么优化方案
  • 博客网站建设免费推广方法
  • 塑胶包装东莞网站建设太原百度快速优化排名
  • 怎么通过做网站赚钱吗百度快照优化培训班
  • 泉州最专业手机网站建设开发百家号权重查询站长工具
  • 网站开发文档有哪些自建网站流程
  • 从网站下载壁纸做海报涉及百度推广优化师是什么
  • 网站开发有没有前途seo培训
  • 郑州建设银行网站房贷网点在哪里软文写作经验
  • 手机移动端网站怎么做seo电视剧排行榜百度搜索风云榜
  • 食品招商网网站推广关键词排名优化
  • 网站推广费用价格关键词优化平台有哪些
  • 深圳华强北二手手机seo外链网
  • 主题 外贸网站 模板手机怎么自己制作网页
  • 众筹网站怎么做推广怎么开发一个网站
  • 秦皇岛海三建设怎么样优化公司排名
  • 南昌网站开发模板sq网站推广
  • 沈阳网站推广优化公司哪家好浙江百度推广开户
  • 替别人做网站公司网站如何建设
  • 容桂做网站优化公司网站
  • 网站建设有什么岗位单页网站seo优化
  • 自己做的网站怎样赚钱吗哈尔滨seo公司
  • 网店代运营哪里找谷歌seo价格
  • 郎溪做网站淄博seo推广
  • 上海网站建设的意义谷歌优化师
  • nginx 网站开发东莞网络营销公司
  • 周口做网站哪家好收录之家
  • 平板做网站服务器百度广告公司
  • 湘潭建设网站制作seo教程技术整站优化