iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >SpringBoot bean如何查询加载顺序
  • 734
分享到

SpringBoot bean如何查询加载顺序

2023-07-05 11:07:06 734人浏览 泡泡鱼
摘要

这篇“SpringBoot bean如何查询加载顺序”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBo

这篇“SpringBoot bean如何查询加载顺序”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBoot bean如何查询加载顺序”文章吧。

背景

SpringBoot bean 加载顺序如何查看,想看加载了哪些bean, 这些bean的加载顺序是什么?

实际加载顺序不受控制,但会有一些大的原则:

按照字母顺序加载(同一文件夹下按照字母数序;不同文件夹下,先按照文件夹命名的字母顺序加载)
2、不同的bean声明方式不同的加载时机,顺序总结:@ComponentScan > @Import > @Bean
   这里的ComponentScan指@ComponentScan及其子注解,Bean指的是@configuration + @bean
   同时需要注意的是:
   (1)Component及其子注解申明的bean是按照字母顺序加载的
   (2)@configuration + @bean是按照定义的顺序依次加载的
   (3)@import的顺序,就是bean的加载顺序
   (4)在xml中,通过<bean id="">方式声明的bean也是按照代码的编写顺序依次加载的
   (5)同一类中加载顺序:Constructor >> @Autowired >> @PostConstruct >> @Bean
   (6)同一类中加载顺序:静态变量 / 静态代码块 >> 构造代码块 >> 构造方法(需要特别注意的是静态代码块的执行并不是优先所有的bean加载,只是在同一个类中,静态代码块优先加载)

探索-源码

入口:

public class TestApplication {public static void main(String[] args) {try {SpringApplication.run(TestApplication.class, args);LOGGER.info("SpringBoot Application Start!!!");} catch (Throwable e) {throw e;}}}

其中 里面的run方法为:

public ConfigurableApplicationContext run(String... args) {long startTime = System.nanoTime();DefaultBootstrapContext bootstrapContext = createBootstrapContext();ConfigurableApplicationContext context = null;configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();context.setApplicationStartup(this.applicationStartup);prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);**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);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);}return context;}

refreshContext(context);

private void refreshContext(ConfigurableApplicationContext context) {if (this.reGISterShutdownHook) {shutdownHook.registerApplicationContext(context);}**refresh**(context);}

AbstractApplicationContext#refresh

然后看倒数第二行:finishBeanFactoryInitialization(beanFactory);

org.springframework.context.support.AbstractApplicationContext#refresh

@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.**finishBeanFactoryInitialization(beanFactory);**// Last step: publish corresponding event.finishRefresh();}

finishBeanFactoryInitialization(beanFactory)

然后看最后一行:beanFactory.preInstantiateSingletons();

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no BeanFactoryPostProcessor// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transfORMers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.**beanFactory.preInstantiateSingletons();**}

beanFactory.preInstantiateSingletons()

在这里会对 beanDefinitionNames 进行遍历,然后进行 bean的实例化 和 组装

因此这里的 beanDefinitionNames 这个列表决定了bean 的 注册顺序。

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

@Overridepublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.**List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);**// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}}

SpringBoot bean如何查询加载顺序

如果不能看,像图中一样,不能找到java.util.list这个类,可以使用下面这个方式,亲测有效:

beanDefinitionNames.toArray()

SpringBoot bean如何查询加载顺序

后面的bean就不展示顺序了。感兴趣的读者可以看自己springBoot项目的。

进一步思考

beanDefinitionNames 列表如何来的呢?

答案是 ConfigurationClassPostProcessor 通过扫描 代码+注解生成的,讲bean 扫描解析成 beanDefinition, 同时把 bean定义,beanDefinition,注册到 BeanDefinitionRegistry, 故有了beanDefinitionNames list。

以上就是关于“SpringBoot bean如何查询加载顺序”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: SpringBoot bean如何查询加载顺序

本文链接: https://www.lsjlt.com/news/351419.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SpringBoot bean如何查询加载顺序
    这篇“SpringBoot bean如何查询加载顺序”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBo...
    99+
    2023-07-05
  • springboot中怎么控制bean的加载顺序
    这期内容当中小编将会给大家带来有关springboot中怎么控制bean的加载顺序,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 1.为什么需要控制加载顺序springboot遵从约定大于配置的...
    99+
    2023-06-16
  • spring或者springboot调整bean加载顺序的方式
    目录spring 或者spring boot 调整bean 的加载顺序1、使用@Order调整配置类加载顺序2、使用@Order调整配置类加载顺序3、实现ordered 接口:spr...
    99+
    2023-03-01
    spring boot bean加载顺序 spring bean加载顺序
  • SpringBootbean查询加载顺序流程详解
    目录背景探索-源码进一步思考背景 SpringBoot bean 加载顺序如何查看,想看加载了哪些bean, 这些bean的加载顺序是什么? 实际加载顺序不受控制,但会有一些大的原则...
    99+
    2023-03-12
    SpringBoot bean加载顺序 SpringBoot加载bean
  • java如何查看jar包加载顺序
    目录查看jar包加载顺序查看具体的class从哪个jar保重加载的jar包中类的加载顺序(类名冲突)javac是用来编译*.java文件的在windows下,多个jar包用分号隔开查...
    99+
    2022-11-12
  • Mysql中如何指定顺序排序查询
    小编给大家分享一下Mysql中如何指定顺序排序查询,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!实例如下前端主要用Vue框架,要...
    99+
    2022-10-18
  • SpringBoot中如何实现自己的bean优先加载
    这篇文章主要介绍“SpringBoot中如何实现自己的bean优先加载”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot中如何实现自己的bean优先加载”文章能帮助大家解决问题。一、...
    99+
    2023-07-06
  • axuer如何看内联框架加载顺序
    本篇内容介绍了“axuer如何看内联框架加载顺序”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!axuer看内联框架加载顺序打开Axure软件...
    99+
    2023-07-06
  • javascript如何按顺序加载运行js方法
    这篇文章将为大家详细讲解有关javascript如何按顺序加载运行js方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。浏览器会异步加载 javascript 文件,但是...
    99+
    2022-10-19
  • mysql如何给查询加序号
    本文小编为大家详细介绍“mysql如何给查询加序号”,内容详细,步骤清晰,细节处理妥当,希望这篇“mysql如何给查询加序号”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。 ...
    99+
    2022-10-19
  • mysql查询如何添加序号
    这篇文章主要讲解了“mysql查询如何添加序号”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql查询如何添加序号”吧! m...
    99+
    2023-02-15
    mysql
  • Mybatis如何按顺序查询出对应的数据字段
    目录Mybatis按顺序查询出对应的数据字段解决方法Mybatis基本查询、条件查询、查询排序Mybatis按顺序查询出对应的数据字段 今天遇到一个问题,就是写xml文件时,返回的顺...
    99+
    2022-11-13
  • Angularjs如何添加排序查询功能
    小编给大家分享一下Angularjs如何添加排序查询功能,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体代码如下所示: <!DOCTYPE html> &...
    99+
    2022-10-19
  • 在 MySQL 中,如何使用查询未检索到的列来指定排序顺序?
    实际上,我们知道我们可以借助 ORDER BY 子句指定排序顺序。我们需要编写 ORDER BY 关键字,后跟要对表进行排序的列的名称。我们不必在查询中的 SELECT 关键字后面使用该列名称。示例mysql> Select ...
    99+
    2023-10-22
  • springboot如何查找配置文件路径的顺序和其优先级别
    目录查找配置文件路径的顺序和其优先级别一、springboot查找配置文件路径的顺序和其优先级别二、同路径下springboot配置文件不生效的原因查找配置文件路径的顺序和其优先级别...
    99+
    2022-11-13
  • JPA @Basic单表查询如何实现大字段懒加载
    JPA @Basic单表查询实现大字段懒加载 近期看了JPA@Basic注解的使用,看到该注解可以设置字段的懒加载。 1.以前碰到的懒加载: 我们知道,多表关联的时候,我们是可以配置...
    99+
    2022-11-12
  • 小程序开发如何添加节点的滚动位置查询请求
    本文小编为大家详细介绍“小程序开发如何添加节点的滚动位置查询请求”,内容详细,步骤清晰,细节处理妥当,希望这篇“小程序开发如何添加节点的滚动位置查询请求”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。添加节点的滚动...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作