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

Spring Bean生命周期(基于spring-beans-6.2.6分析)

Spring Bean生命周期(基于spring-beans-6.2.6分析)

SpringApplication.run()└─> createApplicationContext()└─> refreshContext()└─> AbstractApplicationContext.refresh()├─> prepareRefresh()├─> obtainFreshBeanFactory()        ← 加载 BeanDefinition├─> prepareBeanFactory()            ← 设置基础属性├─> invokeBeanFactoryPostProcessors()← 修改 BeanDefinition├─> registerBeanPostProcessors()    ← 注册后置处理器├─> initMessageSource()├─> initApplicationEventMulticaster()├─> onRefresh()                     ← 子类扩展点(如 Web 应用)├─> registerListeners()├─> finishBeanFactoryInitialization()|   └─> preInstantiateSingletons()  ← 实例化单例 Bean|       └─> getBean()               ← 获取 Bean 实例|           └─> doGetBean()|               └─> getSingleton()  ← 三级缓存机制|                   └─> singletonFactory.getObject()|                       └─> createBean()|                           ├─> doCreateBean()|                           |   ├─> createBeanInstance() ← 构造函数实例化|                           |   ├─> populateBean()       ← 属性填充|                           |   └─> initializeBean()     ← 初始化(@PostConstruct 等)└─> finishRefresh()

HawkeyeServer

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

SpringApplication

public ConfigurableApplicationContext run(String... args) {Startup startup = SpringApplication.Startup.create();if (this.properties.isRegisterShutdownHook()) {shutdownHook.enableShutdownHookAddition();}DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();ConfigurableApplicationContext context = null;this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner = this.printBanner(environment);context = this.createApplicationContext();context.setApplicationStartup(this.applicationStartup);this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 初始刷新化容器this.refreshContext(context);this.afterRefresh(context, applicationArguments);startup.started();if (this.properties.isLogStartupInfo()) {(new StartupInfoLogger(this.mainApplicationClass, environment)).logStarted(this.getApplicationLog(), startup);}listeners.started(context, startup.timeTakenToStarted());this.callRunners(context, applicationArguments);} catch (Throwable ex) {throw this.handleRunFailure(context, ex, listeners);}try {if (context.isRunning()) {listeners.ready(context, startup.ready());}return context;} catch (Throwable ex) {throw this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);}}private void refreshContext(ConfigurableApplicationContext context) {if (this.properties.isRegisterShutdownHook()) {shutdownHook.registerApplicationContext(context);}this.refresh(context);}protected void refresh(ConfigurableApplicationContext applicationContext) {applicationContext.refresh();}

AbstractApplicationContext

 public void refresh() throws BeansException, IllegalStateException {this.startupShutdownLock.lock();try {this.startupShutdownThread = Thread.currentThread();StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");this.prepareRefresh();ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();this.prepareBeanFactory(beanFactory);try {this.postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");this.invokeBeanFactoryPostProcessors(beanFactory);this.registerBeanPostProcessors(beanFactory);beanPostProcess.end();this.initMessageSource();this.initApplicationEventMulticaster();this.onRefresh();this.registerListeners();// 完成 BeanFactory 的初始化,实例化所有非懒加载的单例 Bean。this.finishBeanFactoryInitialization(beanFactory);this.finishRefresh();} catch (Error | RuntimeException var12) {if (this.logger.isWarnEnabled()) {this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + String.valueOf(var12));}this.destroyBeans();this.cancelRefresh(var12);throw var12;} finally {contextRefresh.end();}} finally {this.startupShutdownThread = null;this.startupShutdownLock.unlock();}}

this.obtainFreshBeanFactory();

// 获取一个全新的 ConfigurableListableBeanFactory 实例,并加载所有的 BeanDefinition。
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); 
public DefaultListableBeanFactory() {this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;this.resolvableDependencies = new ConcurrentHashMap(16);this.beanDefinitionMap = new ConcurrentHashMap(256);this.mergedBeanDefinitionHolders = new ConcurrentHashMap(256);this.primaryBeanNames = ConcurrentHashMap.newKeySet(16);this.allBeanNamesByType = new ConcurrentHashMap(64);this.singletonBeanNamesByType = new ConcurrentHashMap(64);this.beanDefinitionNames = new ArrayList(256);this.manualSingletonNames = new LinkedHashSet(16);this.preInstantiationThread = new NamedThreadLocal("Pre-instantiation thread marker");}

this.invokeBeanFactoryPostProcessors(beanFactory);

// 执行所有的 BeanFactoryPostProcessor,这些处理器可以在 Bean 实例化前修改 BeanDefinition。
this.postProcessBeanFactory(beanFactory);AbstractApplicationContext#PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());// 调用getBean
AbstractApplicationContext#currentRegistryProcessors.add((BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));AbstractBeanFactory#doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly);// 第一次初始化为空的Object sharedInstance = this.getSingleton(beanName);// 第一次初始化将bean的封装创建逻辑放入 sharedInstance = this.getSingleton(beanName, () -> {try {return this.createBean(beanName, mbd, args);} catch (BeansException ex) {this.destroySingleton(beanName);throw ex;}});

this.finishBeanFactoryInitialization(beanFactory);

// 完成 BeanFactory 的初始化,实例化所有非懒加载的单例 Bean。
this.finishBeanFactoryInitialization(beanFactory);// 获取Bean
AbstractBeanFactory#doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)// 使用三级缓存机制获取Bean,解决循环依赖
DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference);protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {if (!this.singletonLock.tryLock()) {return null;}try {singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);if (singletonFactory != null) {// 接口常用于延迟加载对象封装创建逻辑 // 延迟加载 避免过早暴露原始对象,防止后续无法生成代理// 代理对象singletonObject = singletonFactory.getObject();if (this.singletonFactories.remove(beanName) != null) {this.earlySingletonObjects.put(beanName, singletonObject);} else {singletonObject = this.singletonObjects.get(beanName);}}}}} finally {this.singletonLock.unlock();}}}return singletonObject;}// 创建createBean逻辑
// singletonObject = singletonFactory.getObject();等价于singletonObject = createBean(beanName, mbd, args);
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

AbstractAutowireCapableBeanFactory

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 实例化instanceWrapper = this.createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}synchronized(mbd.postProcessingLock) {if (!mbd.postProcessed) {try {this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);}mbd.markAsPostProcessed();}}boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);if (earlySingletonExposure) {if (this.logger.isTraceEnabled()) {this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");}this.addSingletonFactory(beanName, () -> this.getEarlyBeanReference(beanName, mbd, bean));}Object exposedObject = bean;try {// 填充属性this.populateBean(beanName, mbd, instanceWrapper);// 初始化exposedObject = this.initializeBean(beanName, exposedObject, mbd);} catch (Throwable var18) {if (var18 instanceof BeanCreationException bce) {if (beanName.equals(bce.getBeanName())) {throw bce;}}throw new BeanCreationException(mbd.getResourceDescription(), beanName, var18.getMessage(), var18);}if (earlySingletonExposure) {Object earlySingletonReference = this.getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {String[] dependentBeans = this.getDependentBeans(beanName);Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);for(String dependentBean : dependentBeans) {if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}try {this.registerDisposableBeanIfNecessary(beanName, bean, mbd);return exposedObject;} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}}

相关文章:

  • Bootstrap 5学习教程,从入门到精通,Bootstrap 5 提示框(Tooltips) 语法知识点及案例(21)
  • uniapp:微信小程序胶囊「复制链接」灰色处理
  • EEG分类 - Theta 频带 power
  • JimuReport:一款免费的数据可视化报表工具
  • GitLab 17.8 备份秘籍:快速获取纯 Git 仓库与核心配置
  • Word2Vec 原理是什么
  • Learning PostgresSQL读书笔记: 第1章 Introduction to PostgreSQL
  • 【AI 测试】测试用例设计:人工智能语言大模型性能测试用例设计
  • 【数码管向左出现与消失滚动“456789Ab”】2022-4-25
  • 【数据结构】_二叉树OJ第二弹(返回数组的遍历专题)
  • 如何利用Charles抓包工具提升API调试与性能优化
  • 【Java面试】什么是一致性Hash算法
  • 原生微信小程序网络请求与上传接口封装实战指南
  • 黑马程序员苍穹外卖DAY1
  • Java 程序设计试题​
  • 拼多多API限流机制破解:分布式IP池搭建与流量伪装方案
  • 从 0 到 1 构建 Graph RAG 系统:本地图谱 + 通义千问落地实践
  • OVS Faucet练习(下)
  • matlab实现大地电磁二维正演
  • 吃透 Golang 基础:测试
  • 个人或主题网站建设实验体会/住房和城乡建设部
  • 做网站空间重要还是程序重要/外汇交易平台
  • 个人备案的网站可以做宣传/站长seo推广
  • 学校网站设计首页/企业邮箱如何申请注册
  • 手机网站可以做公众号/nba西部排名
  • 南京网站制作网页/深圳seo外包公司