SpringBoot源码之Bean的生命周期

news/2024/11/29 6:41:10/

入口方法为SpringApplication#run()
1.SpringApplication#run()

/*** 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) {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);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) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {if (context.isRunning()) {Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}return context;}

2.SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>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);try {// 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();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}

3.SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>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 SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {getBean(beanName);}}else {// 此处就是初始化bean的方法getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {// 此处就是解决循环依赖的代码Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);smartSingleton.afterSingletonsInstantiated();smartInitialize.end();}}}

解决循环依赖的代码如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 尝试从缓存中获取成品的目标对象,如果存在,则直接返回Object singletonObject = this.singletonObjects.get(beanName);// 如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,在前面的讲解中,第一次尝试获取A对象// 的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候,这里的if判断就会为trueif (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {// 这里的singletonFactories是一个Map,其key是bean的名称,而值是一个ObjectFactory类型的// 对象,这里对于A和B而言,调用图其getObject()方法返回的就是A和B对象的实例,无论是否是半成品ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 获取目标对象的实例singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}
  • 一级缓存,singletonObjects 单例缓存,存储已经实例化的单例bean。
  • 二级缓存,earlySingletonObjects 提前暴露的单例缓存,这里存储的bean是刚刚构造完成,但还会通过属性注入bean。
  • 三级缓存,singletonFactories 生产单例的工厂缓存,存储工厂。

解决原理如下:

  1. 在第一层中,先去获取 A 的 Bean,发现没有就准备去创建一个,然后将 A 的代理工厂放入“三级缓存”(这个 A 其实是一个半成品,还没有对里面的属性进行注入),但是 A 依赖 B 的创建,就必须先去创建 B;
  2. 在第二层中,准备创建 B,发现 B 又依赖 A,需要先去创建 A,去创建 A,因为第一层已经创建了 A 的代理工厂,直接从“三级缓存”中拿到 A 的代理工厂,获取 A 的代理对象,放入“二级缓存”,并清除“三级缓存”;
  3. 有了 A 的代理对象,对 A 的依赖完美解决(这里的 A 仍然是个半成品),B 初始化成功。在 B 初始化成功,完成 A 对象的属性注入,然后再填充 A 的其它属性,以及 A 的其它步骤(包括 AOP),完成对 A 完整的初始化功能(这里的 A 才是完整的 Bean)。
  4. 将 A 放入“一级缓存”。

4.SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()=>AbstractBeanFactory#getBean() => AbstractBeanFactory#doGetBean()=>AbstractBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#doCreateBean()

bean的生命周期:
1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
跟进doCreateBean()

@Override  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  throws BeanCreationException {  if (logger.isTraceEnabled()) {  logger.trace("Creating instance of bean '" + beanName + "'");  }  RootBeanDefinition mbdToUse = mbd;  // Make sure bean class is actually resolved at this point, and  // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {  mbdToUse = new RootBeanDefinition(mbd);  mbdToUse.setBeanClass(resolvedClass);  }  // Prepare method overrides.  try {  mbdToUse.prepareMethodOverrides();  }  catch (BeanDefinitionValidationException ex) {  throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),  beanName, "Validation of method overrides failed", ex);  }  try {  // 1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiationObject bean = resolveBeforeInstantiation(beanName, mbdToUse);  if (bean != null) {  return bean;  }  }  catch (Throwable ex) {  throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,  "BeanPostProcessor before instantiation of bean failed", ex);  }  try {  // 跟进doCreateBean()Object beanInstance = doCreateBean(beanName, mbdToUse, args);  if (logger.isTraceEnabled()) {  logger.trace("Finished creating instance of bean '" + beanName + "'");  }  return beanInstance;  }  catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {  // A previously detected exception with proper bean creation context already,  // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex;  }  catch (Throwable ex) {  throw new BeanCreationException(  mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);  }  
}

2.创建bean实例
跟进populateBean()
跟进initializeBean()

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  throws BeanCreationException {  // Instantiate the bean.  BeanWrapper instanceWrapper = null;  if (mbd.isSingleton()) {  instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  }  if (instanceWrapper == null) { // 2.创建bean实例 instanceWrapper = createBeanInstance(beanName, mbd, args);  }  Object bean = instanceWrapper.getWrappedInstance();  Class<?> beanType = instanceWrapper.getWrappedClass();  if (beanType != NullBean.class) {  mbd.resolvedTargetType = beanType;  }  // Allow post-processors to modify the merged bean definition.  synchronized (mbd.postProcessingLock) {  if (!mbd.postProcessed) {  try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  }  catch (Throwable ex) {  throw new BeanCreationException(mbd.getResourceDescription(), beanName,  "Post-processing of merged bean definition failed", ex);  }  mbd.markAsPostProcessed();  }  }  // Eagerly cache singletons to be able to resolve circular references  // even when triggered by lifecycle interfaces like BeanFactoryAware.   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  isSingletonCurrentlyInCreation(beanName));  if (earlySingletonExposure) {  if (logger.isTraceEnabled()) {  logger.trace("Eagerly caching bean '" + beanName +  "' to allow for resolving potential circular references");  }  addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  }  // Initialize the bean instance.  Object exposedObject = bean;  try {// 跟进populateBean()populateBean(beanName, mbd, instanceWrapper); // 跟进initializeBean() exposedObject = initializeBean(beanName, exposedObject, mbd);  }  catch (Throwable ex) {  if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {  throw bce;  }  else {  throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);  }  }  if (earlySingletonExposure) {  Object earlySingletonReference = getSingleton(beanName, false);  if (earlySingletonReference != null) {  if (exposedObject == bean) {  exposedObject = earlySingletonReference;  }  else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {  String[] dependentBeans = getDependentBeans(beanName);  Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);  for (String dependentBean : dependentBeans) {  if (!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.");  }  }  }  }  // Register bean as disposable.  try {  registerDisposableBeanIfNecessary(beanName, bean, mbd);  }  catch (BeanDefinitionValidationException ex) {  throw new BeanCreationException(  mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  }  return exposedObject;  
}

3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation
4.注入bean属性

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {  if (bw == null) {  if (mbd.hasPropertyValues()) {  throw new BeanCreationException(  mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");  }  else {  // Skip property population phase for null instance.  return;  }  }  if (bw.getWrappedClass().isRecord()) {  if (mbd.hasPropertyValues()) {  throw new BeanCreationException(  mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");  }  else {  // Skip property population phase for records since they are immutable.  return;  }  }  // 3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiationfor (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {  if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {  return;  }  }  }  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);  int resolvedAutowireMode = mbd.getResolvedAutowireMode();  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {  MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  // Add property values based on autowire by name if applicable.  if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {  autowireByName(beanName, mbd, bw, newPvs);  }  // Add property values based on autowire by type if applicable.  if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {  autowireByType(beanName, mbd, bw, newPvs);  }  pvs = newPvs;  }  if (hasInstantiationAwareBeanPostProcessors()) {  if (pvs == null) { pvs = mbd.getPropertyValues();  }  for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {  PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);  if (pvsToUse == null) {  return;  }  pvs = pvsToUse;  }  }  boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);  if (needsDepCheck) {  PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  checkDependencies(beanName, mbd, filteredPds, pvs);  }  if (pvs != null) {// 4.注入属性  applyPropertyValues(beanName, mbd, bw, pvs);  }  
}

5.设置Aware接口的属性
6.调用BeanPostProcessor的初始化前置方法
7.先((InitializingBean) bean).afterPropertiesSet(),后调用init-method方法,进行初始化操作
8.调用BeanPostProcessor的初始化后置方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {// 5.设置Aware接口的属性invokeAwareMethods(beanName, bean);  Object wrappedBean = bean;  if (mbd == null || !mbd.isSynthetic()) {// 5.调用BeanPostProcessor的初始化前置方法  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  }  try {// 6.调用init-method方法,进行初始化操作  invokeInitMethods(beanName, wrappedBean, mbd);  }  catch (Throwable ex) {  throw new BeanCreationException(  (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);  }  if (mbd == null || !mbd.isSynthetic()) { // 7. 调用BeanPostProcessor的初始化后置方法wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  }  return wrappedBean;  
}

http://www.ppmy.cn/news/40154.html

相关文章

QT 安装 及环境变量配置及出现的错误的解决方法

文章目录QT安装教程(win版)下载链接点击 产品 Qt开发工具点击 下载Qt下滑点击 开源用户下载下滑点击 下载Qt在线安装程序点击 win版本下载打开程序这一步可能遇到的问题1.在自己有Qt账号的情况下&#xff0c;下一步无法点击2.弹出一句话You need to verify your Qt account eai…

企业数据平台建设的基石:构建统一的数据存算能力

随着企业数字化程度的逐步提高&#xff0c;数字化业务对数据管理的需求也持续深化。根据企业本身所处的数字化程度不同&#xff0c;我们将企业的数据平台的建设总结为五个阶段&#xff0c;本篇我们对统一的数据存储与算力做介绍。 — 整体介绍 — 企业发展的战略目标就是为了更…

详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量

一、互斥锁&#xff08;同步&#xff09; 在多任务操作系统中&#xff0c;同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于&#xff0c;公司部门里&#xff0c;我在使用着打印机打印东西的同时&#xff08;还没有打印完&#xff09;&#xff0c;别人刚好也在此…

普通人怎么用ChatGPT-ChatGPT中文版网页

去哪下载ChatGPT ChatGPT是一种自然语言处理算法&#xff0c;其模型是由OpenAI团队开发的。如果你需要使用ChatGPT模型进行自然语言处理任务&#xff0c;你可以从OpenAI官方网站获取模型和相关工具。 具体来说&#xff0c;你可以访问OpenAI的网站&#xff0c;然后在“Researc…

SpringBooot

目录 一、简介 1、使用原因 2、JavaConfig &#xff08;1&#xff09;Configuration注解 &#xff08;2&#xff09;Bean注解 &#xff08;3&#xff09;ImportResource注解 &#xff08;4&#xff09;PropertyResource注解 &#xff08;5&#xff09;案例 3、简介 4…

【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Java:5大最佳Java库

Java是一种面向对象的编程语言&#xff0c;受到全世界数百万程序员的欢迎和使用。让我们重点介绍一下最佳Java库&#xff0c;这些Java库包含扩展Java应用程序功能的包。与传统的Java库相比&#xff0c;它们的受欢迎程度激增。 1.Spring Boot Spring Boot涵盖了你的基本配置和一…

python 调用c++

python中调用c&#xff0c;函数参数用 int类型&#xff0c;返回值为类型1,且返回值为 false。 注意&#xff1a;如果你使用了C中的 false&#xff0c;则返回的是-1。 在 Python中调用C时&#xff0c;你会得到一个名为 bool的类&#xff0c;其中包含了两个成员变量&#xff1a; …