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

做购物网站需要什么服务器沈阳唐朝网络推广

做购物网站需要什么服务器,沈阳唐朝网络推广,wordpress 评论回复邮件通知插件,广州网站建设哪家比较好Springboot 启动时Bean的创建与注入#xff0c;以及对应的源码解读 文章目录 Springboot 启动时Bean的创建与注入#xff0c;以及对应的源码解读构建Web项目流程图#xff1a;堆栈信息#xff1a;堆栈信息简介堆栈信息源码详解1、main:10, DemoApplication (com.xun.demo)2…Springboot 启动时Bean的创建与注入以及对应的源码解读 文章目录 Springboot 启动时Bean的创建与注入以及对应的源码解读构建Web项目流程图堆栈信息堆栈信息简介堆栈信息源码详解1、main:10, DemoApplication (com.xun.demo)2、run:1352, SpringApplication (org.springframework.boot)3、run:1363, SpringApplication (org.springframework.boot)4、run:335, SpringApplication (org.springframework.boot)5、refreshContext:456, SpringApplication (org.springframework.boot)6、refresh:754, SpringApplication (org.springframework.boot)7、refresh:146, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)8、refresh:624, AbstractApplicationContext (org.springframework.context.support)9、finishBeanFactoryInitialization:962, AbstractApplicationContext (org.springframework.context.support)10、preInstantiateSingletons:975, DefaultListableBeanFactory (org.springframework.beans.factory.support) 其他内容 出于研究springboot启动时bean的创建到注入中发生的函数调用的这个目的搭建一个最简单的springboot应用只有一个controller bean没有再手动指定任何其他bean。 先展示一下如何在idea中快速构建一个springboot web demo项目 构建Web项目流程图 在这里推荐一个插件可以在插件市场中搜索 Maven Search安装用于寻找依赖 为了得到堆栈调用信息需要找到InjectionMetadata 类中的 inject 方法打断点调试 堆栈信息 inject:142, InjectionMetadata (org.springframework.beans.factory.annotation) postProcessProperties:508, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) populateBean:1421, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:599, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:522, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:337, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, AbstractBeanFactory$$Lambda$330/0x0000020b811ebab8 (org.springframework.beans.factory.support) getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:335, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:200, AbstractBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons:975, DefaultListableBeanFactory (org.springframework.beans.factory.support) finishBeanFactoryInitialization:962, AbstractApplicationContext (org.springframework.context.support) refresh:624, AbstractApplicationContext (org.springframework.context.support) refresh:146, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context) refresh:754, SpringApplication (org.springframework.boot) refreshContext:456, SpringApplication (org.springframework.boot) run:335, SpringApplication (org.springframework.boot) run:1363, SpringApplication (org.springframework.boot) run:1352, SpringApplication (org.springframework.boot) main:10, DemoApplication (com.xun.demo)堆栈信息简介 这个堆栈信息展示了 Spring Boot 在启动过程中如何创建和注入 bean 的详细过程。下面是对每个函数调用的简单解释详细代码解释在后面进行 inject:142, InjectionMetadata (org.springframework.beans.factory.annotation) InjectionMetadata 是一个 Spring 类用于处理注入点元数据。inject 方法负责实际的注入操作根据注解如 Autowired将依赖注入到目标 bean 中。 postProcessProperties:508, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) AutowiredAnnotationBeanPostProcessor 是一个 BeanPostProcessor负责处理 Autowired 和 Value 注解。postProcessProperties 方法在 Spring 容器实例化 bean 之后但在它们的依赖项被注入之前被调用用于处理依赖注入。 populateBean:1421, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) populateBean 方法用于填充给定 bean 实例的属性。这包括对 Autowired、Value 等注解的处理并将相应的依赖注入到 bean 中。 doCreateBean:599, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean 方法负责实际创建一个新的 bean 实例包括调用其构造函数、应用工厂后处理器、自动装配和初始化。 createBean:522, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean 方法是 doCreateBean 的高层次包装器负责创建并初始化一个新的 bean 实例。 lambda$doGetBean$0:337, AbstractBeanFactory (org.springframework.beans.factory.support) 这是一个 lambda 表达式作为回调传递给 getSingleton 方法负责返回一个单例 bean 实例。 getObject:-1, AbstractBeanFactory$$Lambda$330/0x0000020b811ebab8 (org.springframework.beans.factory.support) 这是 lambda 表达式的实际实现用于从单例注册表中获取或创建一个单例 bean。 getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) getSingleton 方法从单例缓存中获取 bean 实例如果 bean 不存在则创建并缓存它。 doGetBean:335, AbstractBeanFactory (org.springframework.beans.factory.support) doGetBean 方法负责实际获取一个 bean 实例包括处理依赖注入和初始化。 getBean:200, AbstractBeanFactory (org.springframework.beans.factory.support) getBean 方法是 doGetBean 的高层次包装器用于获取一个 bean 实例。 preInstantiateSingletons:975, DefaultListableBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons 方法负责提前实例化所有非延迟加载的单例 bean确保它们在应用启动时就被创建和初始化。 finishBeanFactoryInitialization:962, AbstractApplicationContext (org.springframework.context.support) finishBeanFactoryInitialization 方法在 Spring 容器刷新期间被调用完成 bean 工厂的初始化包括实例化所有剩余的单例 bean。 refresh:624, AbstractApplicationContext (org.springframework.context.support) refresh 方法是 Spring 应用上下文刷新逻辑的入口点负责重新加载 bean 定义、初始化 Spring 环境和 bean 工厂。 refresh:146, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context) 这是 ServletWebServerApplicationContext 类中 refresh 方法的实现用于刷新 Web 应用上下文。 refresh:754, SpringApplication (org.springframework.boot) refresh 方法是 Spring Boot 应用启动过程中刷新应用上下文的关键步骤。 refreshContext:456, SpringApplication (org.springframework.boot) refreshContext 方法用于刷新 Spring 应用上下文确保所有 bean 定义和依赖关系都被正确加载和初始化。 run:335, SpringApplication (org.springframework.boot) run 方法是 Spring Boot 应用的主要入口点负责启动 Spring 应用上下文。 run:1363, SpringApplication (org.springframework.boot) 这是 run 方法的一种签名通常用于启动 Spring Boot 应用。 run:1352, SpringApplication (org.springframework.boot) 这是 run 方法的一种签名通常用于启动 Spring Boot 应用。 main:10, DemoApplication (com.xun.demo) 这是应用的主类 DemoApplication 的 main 方法是 Spring Boot 应用的入口点。 通过这些方法调用Spring Boot 应用在启动过程中创建和注入 bean确保所有依赖关系都被正确解析和注入。 堆栈信息源码详解 先从栈底部的main方法开始看起。 Springboot 启动时Bean的创建与注入二-面试热点-springboot源码解读-xunznux Springboot 的Bean生命周期五步、七步、十步详解以及框架源码解读 1、main:10, DemoApplication (com.xun.demo) SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}这个代码是一个典型的 Spring Boot 应用程序的入口类下面是对每个部分的详细解释 SpringBootApplication 这个注解是一个组合注解它结合了以下三个常用的 Spring 注解 SpringBootConfiguration: 表示这是一个 Spring Boot 配置类等同于 Spring 的 Configuration 注解。EnableAutoConfiguration: 这个注解告诉 Spring Boot 根据添加的依赖自动配置 Spring 应用程序。ComponentScan: 这个注解启用组件扫描让 Spring 找到并注册带有 Component、Service、Repository 和 Controller 等注解的类。 public class DemoApplication 这是 Spring Boot 应用的主类命名为 DemoApplication。按照惯例Spring Boot 应用的主类通常位于源码目录的根包下以便能够扫描到该包及其子包中的所有组件。 public static void main(String[] args) 这是 Java 应用程序的入口点。main 方法是应用程序启动时第一个执行的方法。 SpringApplication.run(DemoApplication.class, args) 这个静态方法启动了 Spring Boot 应用程序。以下是一些关键点 SpringApplication.run 方法负责启动 Spring 应用上下文启动内嵌的服务器例如 Tomcat并初始化 Spring 环境。DemoApplication.class 是应用的主类它包含 SpringBootApplication 注解使其成为 Spring Boot 应用的配置类。args 是传递给应用的命令行参数。 当 SpringApplication.run 被调用时Spring Boot 会执行以下步骤 创建并启动 SpringApplication 实例。准备 SpringApplication 实例例如读取并解析命令行参数。创建并刷新应用上下文包括创建所有单例 bean。启动嵌入式服务器例如 Tomcat。执行所有 CommandLineRunner 和 ApplicationRunner bean。 这个简单的 Spring Boot 应用程序入口类通过 SpringBootApplication 注解和 SpringApplication.run 方法启动了一个完整的 Spring Boot 应用包含自动配置和内嵌服务器简化了 Spring 应用的开发和部署。 2、run:1352, SpringApplication (org.springframework.boot) /*** Static helper that can be used to run a {link SpringApplication} from the* specified source using default settings.* param primarySource the primary source to load* param args the application arguments (usually passed from a Java main method)* return the running {link ApplicationContext}*/ public static ConfigurableApplicationContext run(Class? primarySource, String... args) {return run(new Class?[] { primarySource }, args); }这是一个静态辅助方法可以使用默认设置从指定的源运行一个 SpringApplication。参数 primarySource 是要加载的主要源通常是一个带有 SpringBootApplication 注解的主类。参数 args 是应用程序的参数通常是从 Java 主方法传递的命令行参数。返回正在运行的 ApplicationContext这是 Spring 应用程序上下文的表示。 这个静态 run 方法是启动 Spring Boot 应用程序的便捷方法。它接受一个主要源类和应用程序参数将主要源类包装成一个数组然后调用另一个 run 方法来启动应用程序。最终返回一个 ConfigurableApplicationContext表示应用程序的运行上下文。 3、run:1363, SpringApplication (org.springframework.boot) /*** Static helper that can be used to run a {link SpringApplication} from the* specified sources using default settings and user supplied arguments.* param primarySources the primary sources to load* param args the application arguments (usually passed from a Java main method)* return the running {link ApplicationContext}*/ public static ConfigurableApplicationContext run(Class?[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args); }这个静态 run 方法是启动 Spring Boot 应用程序的便捷方法。它接受一个主要源类数组和应用程序参数创建一个 SpringApplication 实例并调用它的 run 方法来启动应用程序。最终返回一个 ConfigurableApplicationContext表示应用程序的运行上下文。 4、run:335, SpringApplication (org.springframework.boot) /*** Run the Spring application, creating and refreshing a new {link ApplicationContext}.* param args the application arguments (usually passed from a Java main method)* return a running {link ApplicationContext}*/ public ConfigurableApplicationContext run(String... args) {// 创建一个用于记录启动时间和事件的 Startup 实例Startup startup Startup.create();// 如果启用了 registerShutdownHook注册一个 JVM 关闭钩子if (this.registerShutdownHook) {SpringApplication.shutdownHook.enableShutdownHookAddition();}// 创建一个 DefaultBootstrapContext 实例用于引导应用程序上下文的初始化DefaultBootstrapContext bootstrapContext createBootstrapContext();// 声明一个 ConfigurableApplicationContext 变量ConfigurableApplicationContext context null;// 配置 headless 属性防止某些图形环境相关的问题configureHeadlessProperty();// 获取应用程序运行的监听器用于在不同阶段触发事件SpringApplicationRunListeners listeners getRunListeners(args);// 通知监听器应用程序正在启动listeners.starting(bootstrapContext, this.mainApplicationClass);try {// 创建一个 ApplicationArguments 实例解析命令行参数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);// 刷新应用程序上下文加载所有 Bean 定义并启动应用程序refreshContext(context);// 在上下文刷新后进行后续操作afterRefresh(context, applicationArguments);// 记录启动时间startup.started();// 如果 logStartupInfo 为 true记录启动信息if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), startup);}// 通知监听器应用程序已启动listeners.started(context, startup.timeTakenToStarted());// 调用所有 CommandLineRunner 和 ApplicationRunner 实现类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);}// 返回运行中的 ConfigurableApplicationContext 实例return context; }这个 run 方法执行了 Spring Boot 应用程序的完整启动过程从准备环境、创建应用程序上下文到通知监听器和调用运行器。通过多个步骤确保应用程序在启动过程中正确配置和初始化。最终返回一个正在运行的 ApplicationContext 实例。 该方法运行一个 Spring 应用程序创建并刷新一个新的 ApplicationContext 实例。ApplicationContext 是 Spring 框架中的核心接口之一代表了 Spring 的 IoC 容器用于管理 Spring 应用中的 beans。 以下是 run 方法的主要流程和作用 创建启动记录实例: 创建一个 Startup 实例用于记录应用启动的时间和事件。 注册 JVM 关闭钩子: 如果配置了 registerShutdownHook则注册一个 JVM 关闭钩子以确保在 JVM 关闭时能正确地进行清理工作。 创建引导上下文: 创建一个 DefaultBootstrapContext 实例用于在应用上下文初始化期间保存引导信息。 配置 headless 属性: 配置 headless 属性以防止在没有显示器环境中运行时的一些问题。 获取运行监听器: 获取 SpringApplicationRunListeners 实例用于在不同的应用启动阶段触发事件。 通知监听器应用程序正在启动: 通知监听器应用程序启动的开始。 解析命令行参数: 创建 ApplicationArguments 实例解析传入的命令行参数。 准备并配置环境: 准备并配置 Spring 的环境对象。 打印启动横幅: 根据环境配置打印应用启动横幅。 创建应用上下文: 创建 ApplicationContext 实例用于管理 Spring beans。 设置应用启动器: 将应用启动器设置到上下文中。 准备应用上下文: 准备应用上下文包括加载 bean 定义等。 刷新应用上下文: 刷新应用上下文实际启动 Spring 容器。 执行刷新后操作: 在上下文刷新后执行一些必要的操作。 记录启动时间: 记录应用程序启动的时间。 记录启动信息: 如果启用了启动信息日志则记录启动信息。 通知监听器应用程序已启动: 通知监听器应用程序已经启动完成。 调用命令行运行器: 调用所有实现 CommandLineRunner 和 ApplicationRunner 接口的类。 处理启动失败: 捕获并处理启动过程中出现的异常。 通知监听器应用程序已就绪: 通知监听器应用程序已经准备就绪可以处理请求。 返回应用上下文: 返回运行中的 ConfigurableApplicationContext 实例。 5、refreshContext:456, SpringApplication (org.springframework.boot) private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {shutdownHook.registerApplicationContext(context);}refresh(context); }注册关闭钩子如果配置了 registerShutdownHook则调用 shutdownHook 的 registerApplicationContext 方法注册应用上下文以便在 JVM 关闭时执行清理操作。刷新应用上下文调用 refresh(context) 方法这个方法是 AbstractApplicationContext 中定义的抽象方法用于刷新应用上下文包括初始化所有单例 beans。 这个过程确保应用上下文在启动时被正确初始化和配置并且所有必要的单例 beans 被实例化和装配。 6、refresh:754, SpringApplication (org.springframework.boot) /*** Refresh the underlying {link ApplicationContext}.* param applicationContext the application context to refresh*/ protected void refresh(ConfigurableApplicationContext applicationContext) {// 调用 ApplicationContext 的 refresh() 方法来执行刷新操作applicationContext.refresh(); }方法用于执行给定应用上下文的刷新操作确保所有的配置和 beans 都是最新的。 7、refresh:146, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context) /*** 覆盖父类的 refresh() 方法执行应用上下文的刷新操作。* throws BeansException 如果 bean 创建或初始化过程中出现问题* throws IllegalStateException 如果应用上下文已经刷新过或处于不合法状态*/ Override public final void refresh() throws BeansException, IllegalStateException {try {// 调用父类的 refresh() 方法执行应用上下文的刷新操作super.refresh();}catch (RuntimeException ex) {// 如果在刷新过程中出现运行时异常则捕获异常并处理WebServer webServer this.webServer;if (webServer ! null) {// 如果存在 WebServer停止并销毁它webServer.stop();webServer.destroy();}// 抛出捕获到的运行时异常向上层传递异常信息throw ex;} }这段代码中的 refresh() 方法是 ApplicationContext 接口的实现方法在 Spring 应用上下文初始化后被调用用于执行上下文的刷新操作。 8、refresh:624, AbstractApplicationContext (org.springframework.context.support) /*** 加载或刷新配置的持久表示该配置可能来自基于Java的配置、XML文件、属性文件、* 关系数据库模式或其他某种格式。* p* 由于这是一个启动方法如果失败它应该销毁已创建的单例* 以避免悬挂资源。换句话说在调用此方法之后要么所有单例都被实例化* 要么根本没有单例被实例化。* * throws BeansException 如果bean工厂无法初始化* throws IllegalStateException 如果已经初始化并且不支持多次刷新尝试*/ Override public void refresh() throws BeansException, IllegalStateException {// 获取锁以确保刷新过程的线程安全this.startupShutdownLock.lock();try {// 记录当前线程作为执行刷新操作的线程this.startupShutdownThread Thread.currentThread();// 开始一个启动步骤用于上下文刷新过程StartupStep contextRefresh this.applicationStartup.start(spring.context.refresh);// 准备刷新过程prepareRefresh();// 通知子类刷新内部bean工厂// 获得一个新的bean工厂实例ConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// 为这个上下文准备bean工厂prepareBeanFactory(beanFactory);try {// 允许上下文子类对bean工厂进行后处理postProcessBeanFactory(beanFactory);// 开始一个启动步骤用于bean后处理StartupStep beanPostProcess this.applicationStartup.start(spring.context.beans.post-process);// 调用注册在上下文中的bean工厂后处理器invokeBeanFactoryPostProcessors(beanFactory);// 注册拦截bean创建的bean后处理器registerBeanPostProcessors(beanFactory);// 结束bean后处理的启动步骤beanPostProcess.end();// 初始化消息源initMessageSource();// 初始化事件多播器initApplicationEventMulticaster();// 在特定的上下文子类中初始化其他特殊beanonRefresh();// 检查监听器bean并注册它们registerListeners();// 实例化所有剩余非懒加载初始化的单例finishBeanFactoryInitialization(beanFactory);// 完成刷新过程finishRefresh();}// 捕获任何运行时异常或错误catch (RuntimeException | Error ex) {// 如果警告日志启用记录异常并取消刷新尝试if (logger.isWarnEnabled()) {logger.warn(在上下文初始化过程中遇到异常 - 取消刷新尝试: ex);}// 销毁已创建的单例以避免资源泄露如果失败应该销毁已创建的单例destroyBeans();// 重置活动标志cancelRefresh(ex);// 将异常传播给调用者throw ex;}// 确保结束上下文刷新的启动步骤finally {contextRefresh.end();}}// 无论刷新成功还是失败都释放锁finally {this.startupShutdownThread null;this.startupShutdownLock.unlock();} }该方法是 AbstractApplicationContext 类中的 refresh() 方法的实现用于刷新 Spring 应用上下文的整个流程。以下是其详细流程总结 获取启动和关闭锁: 获取 startupShutdownLock 锁确保在应用上下文刷新期间不会被其他线程中断。设置当前线程为启动/关闭线程: 将当前线程设置为 startupShutdownThread以便在需要时能够进行相应处理。应用启动步骤记录: 使用 applicationStartup 记录应用启动步骤标记为 “spring.context.refresh”。用于记录上下文刷新过程的性能指标。准备刷新操作: 调用 prepareRefresh() 方法为刷新操作做准备。包括设置必要的环境属性和初始化一些状态。获取新的 Bean 工厂: 调用 obtainFreshBeanFactory() 方法获取一个新的 ConfigurableListableBeanFactory 实例。通常是通过重新加载Bean定义来实现的。为使用准备 Bean 工厂: 调用 prepareBeanFactory(beanFactory) 方法为当前上下文的使用准备 Bean 工厂。包括设置类加载器、注册默认的环境Bean等。后处理 Bean 工厂: 调用 postProcessBeanFactory(beanFactory) 方法允许子类对 Bean 工厂进行后处理。调用 Bean 工厂后处理器: 调用 invokeBeanFactoryPostProcessors(beanFactory) 方法执行注册在上下文中的 Bean 工厂后处理器。注册 Bean 后处理器: 调用 registerBeanPostProcessors(beanFactory) 方法注册拦截 Bean 创建的 Bean 后处理器。初始化消息源: 调用 initMessageSource() 方法初始化该上下文的消息源。初始化应用事件广播器: 调用 initApplicationEventMulticaster() 方法初始化该上下文的应用事件广播器。用于发布和监听应用事件。特定上下文子类的初始化: 调用 onRefresh() 方法初始化特定于该上下文子类的其他特殊 Bean。注册监听器: 调用 registerListeners() 方法检查并注册监听器 Bean。完成 Bean 工厂的初始化: 调用 finishBeanFactoryInitialization(beanFactory) 方法实例化所有剩余的非延迟初始化单例 Bean。完成刷新操作: 调用 finishRefresh() 方法完成应用上下文的刷新。处理异常: 在执行上述步骤的任何过程中如果捕获到 RuntimeException 或 Error则进入异常处理块。 记录警告日志取消刷新尝试。销毁已创建的单例 Bean避免资源泄漏。设置 active 标志为 false。向上层抛出捕获到的异常。 结束应用启动步骤记录: 无论是否发生异常都会调用 contextRefresh.end() 结束应用启动步骤记录。释放启动和关闭锁: 最后在 finally 块中释放 startupShutdownThread解锁 startupShutdownLock确保安全地结束刷新过程。 这个方法的主要目的是确保 Spring 应用上下文能够在启动时进行正确的初始化和配置包括加载配置、注册 Bean、初始化消息源和事件广播器等重要步骤最终保证应用程序能够正常运行。 9、finishBeanFactoryInitialization:962, AbstractApplicationContext (org.springframework.context.support) /*** 完成本上下文的bean工厂初始化初始化所有剩余的单例bean。* p* 此方法执行以下操作* 1. 初始化此上下文的转换服务如果存在名为CONVERSION_SERVICE_BEAN_NAME的bean且类型为ConversionService。* 2. 如果没有BeanFactoryPostProcessor注册过内嵌的值解析器则注册一个默认的环境占位符解析器。* 3. 早期初始化LoadTimeWeaverAware类型的beans以便于尽早注册它们的transformer。* 4. 停止使用临时类加载器进行类型匹配。* 5. 冻结bean定义元数据不再期望进一步的变化。* 6. 实例化所有剩余的非懒加载初始化单例。* * param beanFactory 当前的可配置列表bean工厂*/ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 如果存在转换服务bean初始化转换服务为此上下文初始化转换服务if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {// 设置bean工厂的转换服务beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// 如果没有任何 BeanFactoryPostProcessor例如 PropertySourcesPlaceholderConfigurer bean// 之前注册过嵌入值解析器则注册一个默认的嵌入值解析器// 此时主要用于解析注解属性值中的占位符。if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal - getEnvironment().resolvePlaceholders(strVal));}// 提前初始化 LoadTimeWeaverAware beans以便及早注册它们的转换器 transformer。String[] weaverAwareNames beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {beanFactory.getBean(weaverAwareName, LoadTimeWeaverAware.class);}// 停止使用临时类加载器进行类型匹配beanFactory.setTempClassLoader(null);// 冻结配置允许缓存所有的Bean定义元数据不再期望有进一步的更改。beanFactory.freezeConfiguration();// 实例化所有剩余的非懒加载初始化单例 BeanbeanFactory.preInstantiateSingletons(); }这个方法的主要作用是完成Spring应用上下文中Bean工厂的初始化过程特别是初始化所有剩余的单例Bean。具体来说它执行了一系列步骤来确保Bean工厂的配置和Bean实例的准备工作都已完成。以下是每个步骤的详细解释 初始化转换服务检查是否存在名为CONVERSION_SERVICE_BEAN_NAME的Bean并且该Bean的类型匹配ConversionService。如果存在则将其设置为Bean工厂的转换服务。这一步确保了在Bean属性转换时使用正确的转换服务。注册默认嵌入值解析器如果没有嵌入值解析器则添加一个默认的解析器用于解析注解属性值中的占位符。这一步确保了注解中的占位符能够被正确解析。提前初始化LoadTimeWeaverAware bean获取所有实现了LoadTimeWeaverAware接口的Bean名称并提前初始化这些Bean以便及早注册它们的类加载时转换器。这一步确保了类加载时的增强功能能够正确注册。停止使用临时ClassLoader停止使用临时的ClassLoader进行类型匹配。这一步通常是在Bean定义解析和类型匹配完成后进行的清理工作。冻结Bean定义元数据冻结Bean定义元数据表示不再期望有进一步的更改。这一步确保了Bean定义的稳定性和一致性。实例化所有剩余的单例Bean实例化所有剩余的非懒加载的单例Bean。这一步确保了所有需要立即初始化的单例Bean都已创建并准备就绪。 总结这个方法的整体作用是**确保Spring应用上下文中的Bean工厂已经完全初始化并且所有需要的单例Bean都已实例化。**它通过一系列步骤来配置转换服务、解析占位符、注册类加载时转换器、清理临时资源、冻结配置并最终实例化所有单例Bean从而确保应用上下文的稳定性和一致性。 10、preInstantiateSingletons:975, DefaultListableBeanFactory (org.springframework.beans.factory.support) /*** 确保所有非懒加载的单例Bean都被实例化同时考虑{link org.springframework.beans.factory.FactoryBean FactoryBeans}。* 通常在工厂设置结束时调用如果需要。* throws BeansException 如果某个单例Bean无法创建。* 注意这可能会导致工厂中已经初始化了一些Bean* 在这种情况下请调用{link #destroySingletons()}进行完全清理。* see #destroySingletons()*/ Override public void preInstantiateSingletons() throws BeansException {// 如果日志级别为TRACE则记录预实例化单例Bean的操作。if (logger.isTraceEnabled()) {logger.trace(Pre-instantiating singletons in this);}// 迭代一个Bean定义名称的副本以允许在初始化方法中注册新的Bean定义。// 虽然这可能不是常规工厂引导的一部分但在其他情况下工作正常。ListString beanNames new ArrayList(this.beanDefinitionNames);// 触发所有非懒加载单例Bean的初始化...for (String beanName : beanNames) {RootBeanDefinition bd getMergedLocalBeanDefinition(beanName);// 检查Bean定义是否不是抽象的、是单例的并且不是懒加载的。if (!bd.isAbstract() bd.isSingleton() !bd.isLazyInit()) {// 如果是FactoryBean则获取FactoryBean实例。if (isFactoryBean(beanName)) {Object bean getBean(FACTORY_BEAN_PREFIX beanName);// 如果是SmartFactoryBean并且需要急切初始化则获取Bean实例。if (bean instanceof SmartFactoryBean? smartFactoryBean smartFactoryBean.isEagerInit()) {getBean(beanName);}}else {// 否则直接获取Bean实例。getBean(beanName);}}}// 触发所有适用Bean的后初始化回调...for (String beanName : beanNames) {Object singletonInstance getSingleton(beanName);// 如果Bean实例是SmartInitializingSingleton则调用其afterSingletonsInstantiated方法。if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {StartupStep smartInitialize getApplicationStartup().start(spring.beans.smart-initialize).tag(beanName, beanName);smartSingleton.afterSingletonsInstantiated();smartInitialize.end();}} }这段代码是 DefaultListableBeanFactory 类中的 preInstantiateSingletons 方法用于预实例化所有非延迟初始化的单例 Beans同时考虑到 FactoryBean。主要作用是预实例化Spring应用上下文中的所有非懒加载单例Bean并在所有单例Bean实例化后触发相应的回调方法。通过预实例化可以确保所有必要的Bean在应用启动时已经准备就绪从而提高应用的响应速度和稳定性。 以下是方法的流程总结 日志记录 如果日志级别为 trace则记录日志指示正在预实例化单例 Beans。 复制 Bean 名称列表 创建一个 beanNames 列表复制当前 Bean 工厂中所有的 Bean 名称。这样做是为了允许在初始化方法期间可能注册新的 Bean 定义。可以安全地在初始化过程中注册新的bean定义 实例化所有非延迟初始化的单例 Beans 遍历 beanNames 列表中的每个 Bean 名称。获取与当前 Bean 名称关联的合并的 RootBeanDefinition。检查该 Bean 定义是否为非抽象、单例且非延迟初始化。如果是工厂Bean FactoryBean则首先获取其对应的 FactoryBean 实例如果是 SmartFactoryBean 并且设置为 eagerInit需要急切初始化则立即获取其实例。否则直接通过 getBean(beanName) 方法获取该 Bean 的实例。 触发所有适用 Bean 的后初始化回调 再次遍历 beanNames 列表中的每个 Bean 名称。获取每个 Bean 名称对应的单例实例。如果该实例实现了 SmartInitializingSingleton 接口调用其 afterSingletonsInstantiated() 方法执行后初始化逻辑。这是一个回调方法用于在所有单例Bean实例化后执行一些自定义逻辑。 preInstantiateSingletons方法的**主要作用是确保所有非懒加载的单例beans在应用上下文完全启动之前已经被实例化和初始化。**这一步骤对于依赖于这些beans的其他组件来说至关重要因为它保证了这些beans的可用性。同时它还提供了对那些希望在所有单例beans实例化后执行某些操作的beans的支持通过调用SmartInitializingSingleton接口的afterSingletonsInstantiated方法。 总之preInstantiateSingletons方法是Spring框架上下文启动流程中的一个关键环节它负责最终确定所有非懒加载单例beans的状态为整个应用提供了一个完整且一致的运行时环境。 注由于内容过长剩余的核心方法解释放在下一篇文章中。 Springboot 启动时Bean的创建与注入二-面试热点-springboot源码解读-xunznux Springboot 的Bean生命周期五步、七步、十步详解以及框架源码解读 其他内容 如果对 Golang 实现的Raft共识算法、Golang实现的负载均衡或者 Golang web 项目的demo实现感兴趣的可以看看我的主页各个部分都带有详细的代码解释也可以通过代码仓库获取源码直接运行。 gitee链接
http://www.hkea.cn/news/14488130/

相关文章:

  • 江津网站建设怎么样昆明企业网站设计
  • 北京建设银行网站田村wordpress速度插件
  • 如何做好网站需求分析西安营销策划推广公司
  • 一个电商网站开发需要多久钉钉创建企业
  • 教育系统网站cms展览网站建设
  • 电脑网站建设方案惠州网站模板建站
  • 门户网站首页模板做百度网站多少钱
  • 万众城网站建设建网站金坛哪家强?
  • 做网站设计的提成点是多少网站建设的基本概念
  • 长春百度网站快速优化湛江做网站哪家好
  • 网站推广的主要方法有哪些?室内装修3d动态演示效果图
  • 做网站需要的执照wordpress切换固定链接404
  • 网站流量与带宽国外网页设计评论网站
  • 企业网站的主要内容广州越秀区核酸检测点
  • 建站公司网站模板网页视频制作
  • 单品网站怎么建设棋牌网站搭建公司
  • 站长论坛 激活网站民治做网站公司
  • 厦门做网站多少百度竞价是什么意思?
  • 北京公司网站建wordpress可以做淘宝
  • 婚纱网站怎么做seo网站备案 主办单位
  • 物流怎么弄网站网站建设制作模板网站怎么做
  • wordpress爱好者论坛重庆网站建设seo公司
  • 微网站如何建设网站建设361
  • 青州建网站本地运行wordpress
  • 经典网站设计网站保定百度首页优化
  • 网站建设谈单情景对话用易语言做攻击网站软件下载
  • 淘宝指数网站网站开发算软件开发吗
  • 在小网站上做点击广告wordpress投递文章插件
  • 建设银行流水账网站查询网站没有在工信部备案
  • 网站云模板网站开发相关会议