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

北京建站报价濮阳建设工程交易网中标公示

北京建站报价,濮阳建设工程交易网中标公示,红河州住房和建设局网站,服务商平台支付宝SpringBoot源码系列文章 SpringBoot源码解析(一)#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)#xff1a;启动开始阶段 SpringBoot源码解析(四)#xff1a;解析应用参数args Sp…SpringBoot源码系列文章 SpringBoot源码解析(一)SpringApplication构造方法 SpringBoot源码解析(二)引导上下文DefaultBootstrapContext SpringBoot源码解析(三)启动开始阶段 SpringBoot源码解析(四)解析应用参数args SpringBoot源码解析(五)准备应用环境 SpringBoot源码解析(六)打印Banner SpringBoot源码解析(七)应用上下文结构体系 SpringBoot源码解析(八)Bean工厂接口体系 SpringBoot源码解析(九)Bean定义接口体系 SpringBoot源码解析(十)应用上下文AnnotationConfigServletWebServerApplicationContext构造方法 SpringBoot源码解析(十一)准备应用上下文 目录 前言源码入口一、执行应用上下文初始化器1、获取上下文初始化器2、执行初始化器2.1、DelegatingApplicationContextInitializer2.2、SharedMetadataReaderFactoryContextInitializer2.3、ContextIdApplicationContextInitializer2.4、ConfigurationWarningsApplicationContextInitializer2.5、RSocketPortInfoApplicationContextInitializer2.6、ServerPortInfoApplicationContextInitializer2.7、ConditionEvaluationReportLoggingListener 二、触发应用监听器上下文准备完成三、关闭引导上下文四、触发应用监听器上下文加载完成总结 前言 在前文中我们介绍了应用上下文的构造方法初始化两个组件注解Bean定义读取器和类路径Bean定义扫描器接下来我们将探究下准备应用上下文阶段对外的扩展点。 SpringBoot版本2.7.18SpringApplication的run方法的执行逻辑如下本文将详细介绍第8小节刷新上下文 // SpringApplication类方法 public ConfigurableApplicationContext run(String... args) {// 记录应用启动的开始时间long startTime System.nanoTime();// 1.创建引导上下文用于管理应用启动时的依赖和资源DefaultBootstrapContext bootstrapContext createBootstrapContext();ConfigurableApplicationContext context null;// 配置无头模式属性以支持在无图形环境下运行// 将系统属性 java.awt.headless 设置为 trueconfigureHeadlessProperty();// 2.获取Spring应用启动监听器用于在应用启动的各个阶段执行自定义逻辑SpringApplicationRunListeners listeners getRunListeners(args);// 启动开始方法发布开始事件、通知应用监听器ApplicationListenerlisteners.starting(bootstrapContext, this.mainApplicationClass);try {// 3.解析应用参数ApplicationArguments applicationArguments new DefaultApplicationArguments(args);// 4.准备应用环境包括读取配置文件和设置环境变量ConfigurableEnvironment environment prepareEnvironment(listeners, bootstrapContext, applicationArguments);// 配置是否忽略 BeanInfo以加快启动速度configureIgnoreBeanInfo(environment);// 5.打印启动BannerBanner printedBanner printBanner(environment);// 6.创建应用程序上下文context createApplicationContext();// 设置应用启动的上下文用于监控和管理启动过程context.setApplicationStartup(this.applicationStartup);// 7.准备应用上下文包括加载配置、添加 Bean 等prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 8.刷新上下文完成 Bean 的加载和依赖注入refreshContext(context);// 9.刷新后的一些操作如事件发布等afterRefresh(context, applicationArguments);// 计算启动应用程序的时间并记录日志Duration timeTakenToStartup Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}// 10.通知监听器应用启动完成listeners.started(context, timeTakenToStartup);// 11.调用应用程序中的 CommandLineRunner 或 ApplicationRunner以便执行自定义的启动逻辑callRunners(context, applicationArguments);}catch (Throwable ex) {// 12.处理启动过程中发生的异常并通知监听器handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {// 13.计算应用启动完成至准备就绪的时间并通知监听器Duration timeTakenToReady Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}catch (Throwable ex) {// 处理准备就绪过程中发生的异常handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}// 返回已启动并准备就绪的应用上下文return context; }源码入口 // 7.准备应用上下文包括加载配置、添加 Bean 等 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);/*** 预处理应用上下文在应用上下文刷新之前执行一系列准备工作。* * param bootstrapContext 引导上下文存储启动过程中的关键组件* param context Spring 应用上下文 AnnotationConfigServletWebServerApplicationContext * param environment Spring 运行环境* param listeners Spring 应用运行监听器* param applicationArguments 应用程序运行参数* param printedBanner 启动时显示的 Banner*/ private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {// 设置应用环境context.setEnvironment(environment);// 对ApplicationContext进行处理没啥重要内容略过postProcessApplicationContext(context);// 1. 执行应用程序上下文的初始化器applyInitializers(context);// 2. 触发 contextPrepared 事件通知监听器上下文已准备好listeners.contextPrepared(context);// 3. 关闭引导上下文因为之后不再需要bootstrapContext.close(context);// 记录应用启动信息仅在日志启用时if (this.logStartupInfo) {logStartupInfo(context.getParent() null);logStartupProfileInfo(context);}// 获取 Bean 工厂并注册特定的单例 Bean后面章节注册Bean详解ConfigurableListableBeanFactory beanFactory context.getBeanFactory();// 注册命令行参数使其可被 Spring 容器访问beanFactory.registerSingleton(springApplicationArguments, applicationArguments);// 注册启动 Banner如果存在if (printedBanner ! null) {beanFactory.registerSingleton(springBootBanner, printedBanner);}// 配置 Bean 工厂的属性if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {// 允许/禁止循环依赖Spring 5 改为默认禁用循环依赖((AbstractAutowireCapableBeanFactory) beanFactory).setAllowCircularReferences(this.allowCircularReferences);// 允许/禁止 BeanDefinition 覆盖默认禁止if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}// 如果启用了懒加载则添加Bean工厂后处理器推迟 Bean 初始化// 后面执行Bean工厂后置处理器时候详解if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// 添加属性源排序后处理器确保 PropertySource 注解的顺序正确// PropertySource 注解让你能够加载外部配置文件并将配置文件中的属性注入到 Spring 的 Environment 中context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));// 加载应用的所有源配置类、XML 文件、组件扫描等SetObject sources getAllSources();Assert.notEmpty(sources, Sources must not be empty); // 这里就是将SpringBoot配置类注册为Bean定义放到bean工厂load(context, sources.toArray(new Object[0]));// 4. 触发 contextLoaded 事件通知监听器上下文已加载完成listeners.contextLoaded(context); }一、执行应用上下文初始化器 protected void applyInitializers(ConfigurableApplicationContext context) {// 遍历所有需要应用到应用上下文的初始化器for (ApplicationContextInitializer initializer : getInitializers()) {// 通过 GenericTypeResolver 解析初始化器的泛型类型参数确定所需的上下文类型Class? requiredType GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);// 断言当前上下文的类型是否符合要求指定类型、子类或实现类如果不符合则抛出异常Assert.isInstanceOf(requiredType, context, Unable to call initializer.);// 使用初始化器对应用上下文进行初始化initializer.initialize(context);} }1、获取上下文初始化器 上下文初始化器是在SpringApplication构造方法中读取spring.factories文件获取的这里就是将上下文初始化器集合拿来根据Ordered接口或Order排序 // SpringApplication构造方法中读取spring.factories文件获取的 private ListApplicationContextInitializer? initializers;// 获取应用上下文的初始化器集合 public SetApplicationContextInitializer? getInitializers() {// 将初始化器集合转换为一个不可修改的、有序集合并返回return asUnmodifiableOrderedSet(this.initializers); }// 将一个集合转换为一个不可修改的、有序的 Set private static E SetE asUnmodifiableOrderedSet(CollectionE elements) {// 将集合转换为列表以便对其进行排序ListE list new ArrayList(elements);// 使用 AnnotationAwareOrderComparator 对列表进行排序// 通过Ordered接口或Order排序list.sort(AnnotationAwareOrderComparator.INSTANCE);// 将排序后的列表转换为 LinkedHashSet确保元素的顺序被保留return new LinkedHashSet(list); }debug看下获取到的初始化器 2、执行初始化器 执行初始化器调用ApplicationContextInitializer实现类的initialize方法下面逐一分析。 2.1、DelegatingApplicationContextInitializer 简单描述一下就是通过配置文件属性名context.initializer.classes获取到多个初始化器然后再遍历调用每个初始化器的。 举例 假设在application.properties或通过命令行参数配置了以下内容 context.initializer.classescom.example.MyCustomInitializer,com.example.AnotherInitializerSpring在启动时会解析这个属性并按照顺序实例化并调用 MyCustomInitializer 和 AnotherInitializer 类这些类都应该实现ApplicationContextInitializer接口负责在应用上下文初始化时进行自定义操作。 DelegatingApplicationContextInitializer适用于需要在 Spring 应用程序启动时按顺序动态加载和执行多个不同的应用上下文初始化器的场景特别是在具有多个模块或复杂配置的应用中。例如当需要根据不同的环境配置如开发、测试、生产环境执行不同的初始化任务或者在应用启动时灵活地执行自定义的初始化逻辑如数据库连接配置、安全设置或外部服务的初始化时使用DelegatingApplicationContextInitializer可以帮助通过配置文件集中管理多个初始化器确保它们按照指定的顺序正确执行。 2.2、SharedMetadataReaderFactoryContextInitializer SharedMetadataReaderFactoryContextInitializer 是 Spring 框架中的一个初始化器它在 Spring 应用上下文初始化过程中负责确保 MetadataReaderFactory 实例在整个上下文中共享避免每次进行类路径扫描时都重新创建该工厂实例。MetadataReaderFactory主要用于读取和解析类的元数据尤其是在注解扫描过程中例如扫描 Component, Service, Repository 等注解。通过共享MetadataReaderFactorySharedMetadataReaderFactoryContextInitializer提高了类路径扫描的效率减少了内存消耗和性能开销尤其在大型或复杂的 Spring 应用中能够加速启动过程。 2.3、ContextIdApplicationContextInitializer ContextIdApplicationContextInitializer 是 Spring 框架中的一个初始化器类主要用于为 Spring 应用上下文生成一个唯一的 ID并将其设置到应用上下文的环境中。这个 ID 通常用于标识不同的应用上下文实例尤其在有多个 Spring 应用上下文存在的情况下可以帮助区分它们。 2.4、ConfigurationWarningsApplicationContextInitializer ConfigurationWarningsApplicationContextInitializer 是 Spring 框架中的一个应用上下文初始化器它用于在 Spring 应用程序启动时检查并发出有关配置方面的警告尤其是关于弃用的配置或潜在不推荐的配置。它的主要作用是在应用上下文初始化期间帮助开发者识别不再推荐使用的配置或可能导致问题的配置方式。 2.5、RSocketPortInfoApplicationContextInitializer RSocketPortInfoApplicationContextInitializer 是一个 Spring 应用上下文初始化器专门用于确保RSocket协议相关的端口信息在 Spring 应用启动时得到正确配置和初始化特别适用于使用 RSocket 协议进行高效、双向通信的应用场景如微服务架构和实时通信应用。 2.6、ServerPortInfoApplicationContextInitializer ServerPortInfoApplicationContextInitializer是一个确保在 Spring 启动时正确加载、处理和应用服务器端口信息的初始化器它在处理动态端口配置、跨环境配置或微服务架构中的端口共享方面尤其有用。 2.7、ConditionEvaluationReportLoggingListener ConditionEvaluationReportLoggingListener 是 Spring Framework 中的一个类用于在应用启动过程中记录和输出条件注解如 Conditional的评估报告。它会将 Spring 配置类中的条件评估结果打印到日志中帮助开发者了解哪些条件被满足哪些未被满足以及哪些 Bean 被加载或跳过 举例 如果在启动应用时使用 Conditional 注解条件来控制 Bean 的加载ConditionEvaluationReportLoggingListener 会在日志中输出类似如下的信息 2018-12-04 16:42:52.755 INFO 12345 --- [ main] o.s.boot.autoconfigure.ConditionEvaluationReportLoggingListener : Evaluating conditions on com.example.SomeConfiguration- ConditionalOnProperty (spring.datasource.url) matched Spring DataSource Bean created- ConditionalOnMissingBean (org.springframework.jdbc.datasource.DataSource) matched Spring DataSource Bean created二、触发应用监听器上下文准备完成 listeners内部持有多个SpringApplicationRunListener用于监听Spring应用程序启动过程的生命周期事件这里在上下文准备完成时遍历所有SpringApplicationRunListener触发contextPrepared方法。 // 2. 触发 contextPrepared 事件通知监听器上下文已准备好 listeners.contextPrepared(context);唯一的Spring应用启动监听器EventPublishingRunListener的上下文准备完成方法核心内容就是广播应用上下文初始化事件将其推给合适的监听器匹配监听器的事件类型这里就是匹配上下文初始化事件的监听器 虽然匹配到了如下应用监听器但无操作内容 三、关闭引导上下文 // 3. 关闭引导上下文因为之后不再需要 bootstrapContext.close(context);主要内容就是发布事件给合适的监听器。目前没有此事件的监听器故无任何操作。 // DefaultBootstrapContext类方法 public void close(ConfigurableApplicationContext applicationContext) {// 发布 BootstrapContextClosedEvent 事件通知系统上下文已关闭this.events.multicastEvent(new BootstrapContextClosedEvent(this, applicationContext)); }BootstrapContextClosedEvent的发布和监听机制主要用于在应用程序上下文关闭时进行清理和通知。它适用于需要在应用关闭时执行清理操作、通知其他模块或外部系统、管理资源释放的场景。 四、触发应用监听器上下文加载完成 // 4. 触发 contextLoaded 事件通知监听器上下文已加载完成 listeners.contextLoaded(context);核心内容与上下文准备完成触发的监听器原理一致就是广播特定的事件到合适的监听器这都是spring对外的扩展点创建对应的事件监听器就会在对应的时机触发执行。 如下匹配到的应用监听器也没啥重要内容略过 总结 本文概述了SpringBoot启动过程的准备应用上下文阶段触发上下文初始化器ApplicationContextInitializer、上下文准备完成ApplicationContextInitializedEvent事件监听器、引导上下文关闭BootstrapContextClosedEvent事件监听器、上下文加载完成ApplicationPreparedEvent事件监听器执行时机和流程这些均可作为对外扩展点。
http://www.w-s-a.com/news/947200/

相关文章:

  • yy直播官网seo引擎优化是什
  • 做影视网站违法莫品牌营销是什么
  • 全网最稳最低价自助下单网站wordpress电影网站主题
  • 域名更换网站温州建设工程网站
  • 网站如何优化推广连锁店管理网站开发
  • 伊宁市做网站功能性质网站
  • 北京哪个网站制作公司优化大师免费安装下载
  • 同江佳木斯网站设计做网站联系电话
  • 设计上海展会2023seo网站模板下载
  • 开发一个卖东西的网站多少站长工具永久
  • 公司网站怎么突然多了好多友情链接如何删除宁波有几个区
  • 临沂seo网站推广wordpress新编辑器
  • c2c网站设计店面logo设计制作
  • 网站建设任务执行书重庆今天新闻事件
  • 怎样发布自己的网站南宁制作网站公司
  • wordpress装多站点百度查一下
  • 怎么优化一个网站搭建网站免费空间
  • 山东建设和城乡建设厅注册中心网站首页wordpress安装教材
  • 个人风采网站制作毕节网站开发公司电话
  • 网络网站销售设计主题和设计理念
  • 做网站一般用什么服务器承德专业做网站
  • 松北区建设局网站网站建设分为几种
  • 网站建设的合同 体会智联招聘网站建设情况
  • 记的网站域名wordpress地方信息主题
  • 淄博好的建网站公司网站建设 海口
  • 有人做网站花了10几万2017做啥网站能致富
  • 做网站有什么软件cod建站平台
  • 合肥学校网站建设怎么做免费的产品图片网站
  • 营养早餐网站的设计与制作建设通网站怎么查项目经理在建
  • 浑南区建设局网站永州网站建设公司推荐