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

Spring启动源码分析以及生命周期

一、启动流程

整体代码

AbstractApplicationContext.refresh 为 Spring IOC 容器启动整个逻辑。refresh刷新意味Spring 可以在运行时刷新 BeanFactory ,那么我们不需要重启应用去更新容器。

@Override
public void refresh() throws BeansException, IllegalStateException {
   //1、加锁避免同时关闭或者启动以及线程安全问题
   synchronized (this.startupShutdownMonitor) {
      // 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);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // 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();
      }
   }
}
复制代码

流程分析

1、prepareRefresh-预刷新- PropertySource

刷新前的准备,设置以及 active 状态,最重要的是 初始化 PropertySource (子类按需初始化一些属性值),然后 校验必须的配置属性时可以解析的 。

2、obtainFreshBeanFactory-获得刷新后Beanfactory

通知子类刷新 Beanfactory 并获取刷新后的,子类分两种实现一种是每次刷新重新创建 Beanfactory ,还有一种是不做任何处理仅仅只设置下状态,分别对应可刷新刷新下文- AbstractRefreshableApplicationContext 和 GenericApplicationContext .

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //刷新Beanfactory
	refreshBeanFactory();
    //返回当前BeanFactory
	return getBeanFactory();
}
复制代码

GenericApplicationContext

与为每次刷新创建新的内部 BeanFactory 实例的其他 ApplicationContext 实现相比,此上下文的内部 BeanFactory 从一开始就可用,以便能够在其上注册 BeanDefinition 。 refresh() 只能被调用一次 。内嵌的 BeanFactory 是 DefaultListableBeanFactory 。

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}
//内嵌的BeanFactory
private final DefaultListableBeanFactory beanFactory;
复制代码

AbstractRefreshableApplicationContext

每次刷新都会创建创建一个 BeanFactory 。注意重新重新创建 BeanFactory 为** DefaultListableBeanFactory **!!!

//刷新BeanFactory
protected final void refreshBeanFactory() throws BeansException {
   //存在则销毁
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      //创建新beanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      //配置`Beanfactory` 
      customizeBeanFactory(beanFactory);
      //BeanDefinition 
      loadBeanDefinitions(beanFactory);
       //更新引用
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}
复制代码
  1. 判断 Beanfactory 是否存在,存在则销毁Bean和关闭 Beanfactory

  2. 创建新的 Beanfactory

    实际上是创建** DefaultListableBeanFactory **,参数是获取当前 ParentBeanFactory ,Spring IOC 的层次获取Bean

    protected DefaultListableBeanFactory createBeanFactory() {
       return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    复制代码
  3. 配置 Beanfactory

    配置了是否允许Beandefinition重写和是否允许循环引用

    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
       if (this.allowBeanDefinitionOverriding != null) {
          beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
       }
       if (this.allowCircularReferences != null) {
          beanFactory.setAllowCircularReferences(this.allowCircularReferences);
       }
    }
    复制代码
  4. 加载 BeanDefinition

    最重要的一步,根据不同子类(不同的 ApplicationContext )读取Bean的配置元数据以加载 BeanDefinition ,钩子函数同于创建 BeanFactory 后根据不同应用上下去加载 BeanDefinitions 。加载的 BeanDefinition 注册进( registerBeanDefinition ) beanDefinitionMap ( ConcurrentHashMap )根据元数据配置类型主要分以下4中:

/**
 * Load bean definitions into the given bean factory, typically through
 * delegating to one or more bean definition readers.
 */
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
      throws BeansException, IOException;
//DefaultListableBeanFactory
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

复制代码
  • AbstractXmlApplicationContext :基于XMl配置元数据的上下文,针对不同类型的路径有

    FileSystemXmlApplicationContext :文件系统中XML配置

    ClassPathXmlApplicationContext :classPath下XMl配置

  • AnnotationConfigWebApplicationContext :基于Java注解的配置元数据,也是最常用的。

  • GroovyWebApplicationContext :基于Groovy的Web上下文

  • XmlWebApplicationContext :基于XML的web上下文

3、prepareBeanFactory-预设置Beanfactory的标准配置

配置BeanFactory中一些 标准配置 也是基础配置,如注册环境相关的Bean、 ApplicationContextAwareProcessor 等等。

还有排除一些 Aware 接口的自动装配因为一些 Aware 接口中的方法是 setxxx 开头,所以需要排除。

4、postProcessBeanFactory-Bean工厂的前置处理

用于在 Beanfactory 创建 后的 回调 ,可能需要根据**不同应用上下文(即不同的子类)**对创建后的 Beanfactory 进行设置。此时 BeanDefinition 已经加载完毕,但是bean还未创建,这允许在某些 ApplicationContext 实现中注册特殊的 BeanPostProcessors 等

5、invokeBeanFactoryPostProcessors-执行BeanFactory后置处理器

Spring 预留的扩展点, BeanFactoryPostProcessor 允许我们对已经 加载的 BeanDefinition 进行修改或者添加新的BeanDefinition 。非常重要的 扩展点 ,例如:

(1)配置类解析- ConfigurationClassPostProcessor

ConfigurationClassPostProcessor 完成配置类解析和注册像 @ComponentScan 、 @Import 、 @Bean 、 @ImportSource 导入xml配置文件、 @PropertySource -导入properties文件、 ImportSelector (Spring Boot的自动装配就是注册一个 ImportSelector )等等这些功能都是在这里实现的。以下为配置解析的代码:

protected final SourceClass doProcessConfigurationClass(
      ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
      throws IOException {

   if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
      // Recursively process any member (nested) classes first
      processMemberClasses(configClass, sourceClass, filter);
   }

   // Process any @PropertySource annotations 解析@PropertySource
   for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
         sourceClass.getMetadata(), PropertySources.class,
         org.springframework.context.annotation.PropertySource.class)) {
      if (this.environment instanceof ConfigurableEnvironment) {
         processPropertySource(propertySource);
      }
      //省略日志打印
   }

   // Process any @ComponentScan annotations 组件扫描
   Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
         sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
   if (!componentScans.isEmpty() &&
         !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
      for (AnnotationAttributes componentScan : componentScans) {
         // The config class is annotated with @ComponentScan -> perform the scan immediately
         Set<BeanDefinitionHolder> scannedBeanDefinitions =
               this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
         // Check the set of scanned definitions for any further config classes and parse recursively if needed
         for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
            BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
            if (bdCand == null) {
               bdCand = holder.getBeanDefinition();
            }
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
               parse(bdCand.getBeanClassName(), holder.getBeanName());
            }
         }
      }
   }

   // Process any @Import annotations @Import注解
   processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

   // Process any @ImportResource annotations  @ImportResource导入的xml配置文件
   AnnotationAttributes importResource =
         AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
   if (importResource != null) {
      String[] resources = importResource.getStringArray("locations");
      Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
      for (String resource : resources) {
         String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
         configClass.addImportedResource(resolvedResource, readerClass);
      }
   }

   // Process individual @Bean methods @Bean方法
   Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
   for (MethodMetadata methodMetadata : beanMethods) {
      configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
   }

   // Process default methods on interfaces
   processInterfaces(configClass, sourceClass);

   // Process superclass, if any
   if (sourceClass.getMetadata().hasSuperClass()) {
      String superclass = sourceClass.getMetadata().getSuperClassName();
      if (superclass != null && !superclass.startsWith("java") &&
            !this.knownSuperclasses.containsKey(superclass)) {
         this.knownSuperclasses.put(superclass, configClass);
         // Superclass found, return its annotation metadata and recurse
         return sourceClass.getSuperClass();
      }
   }

   // No superclass -> processing is complete
   return null;
}
复制代码

(2)BeanFactory后置处理器的SPI 扩展: BeanDefinitionRegistryPostProcessor

对标准 BeanFactoryPostProcessor SPI 扩展,允许在常规 BeanFactoryPostProcessor 检测开始之前注册进一步的 bean 定义。特别是, BeanDefinitionRegistryPostProcessor 可以注册进一步的 bean 定义,这些定义反过来定义 BeanFactoryPostProcessor 实例。

6、registerBeanPostProcessors-注册Bean后置处理器

BeanPostProcessor 是在Bean 初始化前后 触发进行扩展,所以在实例化bean之前需要注册 BeanPostProcessor (完成Bean后置器的初始化)。

7、initMessageSource-初始化消息资源

初始化消息资源例如 i18n(国际化)

8、initApplicationEventMulticaster-初始化事件广播器

初始化事件广播器以广播事件。 默认情况 下是 SimpleApplicationEventMulticaster 且所有侦听器都在 调用线程 中调用。这允许恶意侦听器阻塞整个应用程序的危险,但增加了最小的开销。可以指定一个替代任务执行器,让侦听器在不同的线程中执行,例如从线程池中执行。 所以利用Spring事件机制来初始化一个资源的适合建议不要太久(因为会阻塞刷新流程) 。

ps:之前犯过一个错误,由于 HDFSClient 在初始化的时候一旦连不上就会不断重试非常耗时(而且不会错误提示),而这个初始化逻辑是放在 @PostConstruct 导致本地在测试其他代码的时候启动巨慢,所以改成事件机制在收到 ContextRefreshedEvent 后初始化,但是发现还是很慢,然后才发现默认情况下是由刷新线程的来广播的。所以之后改成线程池了。

9、onRefresh-钩子函数

钩子函数表示Beanfactory正在刷新中,用于在实例化单例Bean 之前 处理化一些特殊的Bean。允许 子类 处理一些 特殊的Bean的初始化 。

10、registerListeners-注册Listener

注册监听器相关的Bean,用于处理广播器中的事件

11、finishBeanFactoryInitialization-单例Bean实例化

BeanFactory初始化-实例化 所有 的 单例非延迟加载 的Bean。Bean生命周期也体现在里面。实际上所有Bean的创建**都是通过 getBean **去创建的。

  1. 初始化conversion service
  2. 注册默认的EmbeddedValueResolver
  3. 初始化LoadTimeWeaverAware Bean
  4. 初始化所有的 非懒加载单例 Bean
//DefaultListableBeanFactory类中
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 bean post-processor
   // (such as a PropertyPlaceholderConfigurer 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();
}
复制代码

(1)初始化所有非懒加载的单例Bean

在 DefaultListableBeanFactory 中(也就是创建 BeanFactory )中实现了该方法。遍历所有的Bean名称 通过 getBean 方法去创建哪些 单例非懒加载 的Bean。

@Override
public void preInstantiateSingletons() throws BeansException {
    //日志打印
   // 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... 遍历所有的beanName
   for (String beanName : beanNames) {
       //获取合并的BeanDefinition  MergedBeanDefinition???
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //是单例非懒加载非抽象
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            //先尝试获取其FactoryBean
            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());
               }
               //如果是优先innit??
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
             //非FactoryBean直接创建Bean
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans... 触发特殊的后置SmartInitializingSingleton
   for (String beanName : beanNames) {
       //从单例池种获取
      Object singletonInstance = getSingleton(beanName);
       //如果是SmartInitializingSingleton 则执行后置
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

复制代码

doGetBean -获取Bean

大体是先从缓存中获取,获取不到再判断是否交给父BeanFactory去获取,再根据不同的 Scope 从不同的地方获取Bean,获取不到则创建新的Bean(createBean方法),当然前提时 BeanDefinition 存在。

  1. 单例

    先getSingleton(缓存),获取不到则创建

  2. 原型

    直接CreateBean

  3. 其他

    先从对应 Scope 中获取,获取不到则createBean

//AbstractBeanFactory中的getBean方法都是直接去创建Bean
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
     //转化Bean名称 例如Bean的别名 FactoryBean的前缀等等
	String beanName = transformedBeanName(name);
	Object bean;
	// Eagerly check singleton cache for manually registered singletons. 获取单例Bean
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
	    //日志省略
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// 原型循环依赖无法处理 原型Bean没有缓存因为每次获取都是新的
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
		// 双亲委派模型  当当前上下文不存在BeanDefinition交给父BeanFactory去创建
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent. 
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}
        //以上是类型检查(是否存在) 
		if (!typeCheckOnly) {
            //标记Bean已经创建
			markBeanAsCreated(beanName);
		}

		try {
            //获取合并的BeanDefinition 合并为什么
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);
			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
            //创建其前置Bean(dependsOn)
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance. 是单例
			if (mbd.isSingleton()) {
                //从缓存获取 获取不到则创建Bean
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						destroySingleton(beanName);
						throw ex;
					}
				});
                //从获取的缓存中获取
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
            //原型Bean 
			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
                    //每次创建新的
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
                //其他Scope 从对应的Scope中获取,获取不到在创建
				String scopeName = mbd.getScope();
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
				}
				Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
复制代码

12、finishRefresh

刷新完成,发布Beanfactory创建完成事件

protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();

   // Initialize lifecycle processor for this context.
   initLifecycleProcessor();

   // Propagate refresh to lifecycle processor first. 
   getLifecycleProcessor().onRefresh();

   // Publish the final event. 发布上下文刷新完成时间
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}
复制代码

二、Bean生命周期

大体生命周期可分为4大步骤: 实例化(1)、属性填充(2)、初始化(3

16)、销毁(17 19)

,具体的生命周期如下:

​ 创建时:

  1. Bean实例化

  2. 填充属性值

  3. BeanNameAware 的 setBeanName

  4. BeanClassLoaderAware 的 setBeanClassLoader

  5. BeanFactoryAware 的 setBeanFactory

  6. EnvironmentAware 的 setEnvironment

  7. EmbeddedValueResolverAware 的 setEmbeddedValueResolver

  8. ResourceLoaderAware 的 setResourceLoader (仅在在应用程序上下文中运行时适用)

  9. ApplicationEventPublisherAware 的 setApplicationEventPublisher (仅适用于在应用程序上下文中运行的情况)

  10. MessageSourceAware 的 setMessageSource (仅适用于在应用程序上下文中运行的情况)

  11. ApplicationContextAware 的 setApplicationContext (仅适用于在应用程序上下文中运行的情况)

  12. ServletContextAware 的 setServletContext (仅适用于在Web应用程序上下文中运行的情况)

  13. BeanPostProcessors 的 postProcessBeforeInitialization :bean后置处理器的前置处理

    这里面还有对@PostConstruct注解的处理

  14. InitializingBean 的 afterPropertiesSet

  15. 自定义的初始化方法

  16. BeanPostProcessors 的 postProcessAfterInitialization :bean后置处理器的后置处理

    在关闭bean工厂时,以下生命周期方法:

  17. DestructionAwareBeanPostProcessors 的 postProcessBeforeDestruction 方法

    例如@PreDestroy

  18. DisposableBean 的 destroy 方法

  19. 自定义销毁方法

整体代码

根据源码定位到 Bean 的创建代码为 AbstractAutowireCapableBeanFactory.createBean 。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
   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();
   }//异常处理
   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      //1、一些特殊Bean后置处理器的前置处理 在实例化前调用
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }//异常处理
   try {
       //实际创建Bean
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }//异常处理
   
}
//正常创建Bean的具体逻辑
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、(1)创建实例 
			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. 
        //3、执行MergedBeanDefinitionPostProcessor后置处理器 在初始化之前
		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.postProcessed = true;
			}
		}

		// 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 {
            //4、注入Bean
			populateBean(beanName, mbd, instanceWrapper);
            //5、初始化Bean
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}//异常处理

        //早期暴露
		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()) {
					//抛出异常
					}
				}
			}
		}
		// Register bean as disposable(一次性的).
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}
复制代码

流程分析

1、实例化

创建Bean实例,实例化可分为三大部分:

  • 实例化前置处理

    InstantiationAwareBeanPostProcessor 添加实例化前回调的 BeanPostProcessor 子接口,以及实例化后但在设置显式属性或发生自动装配之前的回调(在 populateBean 中调用)。

  • 创建实例

    使用对应的实例化策略(即三种实例bean的方式)进行实例化

  • 实例化后置处理

    即 MergedBeanDefinitionPostProcessor 允许在bean实例化合并一些元数据到 BeanDefinition 当中,例如依赖注入的元数据就是在此处解析的。

1.1 resolveBeforeInstantiation 创建前置处理

在实例化前的后置处理器,处理一些实例化前的** Aware **。根据源码是执行 InstantiationAwareBeanPostProcessor 相关的后置处理器。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      //如果不是合成的 ??? 并且有实例化前的Aware BeanPostProcessor
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}
//调用实例化前的BeanPostProcessor-InstantiationAwareBeanPostProcessor
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
        //
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
	}
	return null;
}
复制代码

1.2 createBeanInstance创建Bean

根据 BeanDefinition 的配置调用不同的 实例化策略 进行实例化。本质上就是那三种bean的实例化方式- InstantiationStrategy

  • 构造函数

  • 静态工厂

  • 实例工厂

  • 外部实例

    例如在外面实例化,再利用 SingletonBeanRegistry 注册到容器中

//实例化策略
public interface InstantiationStrategy {

	//直接在此工厂中返回具有给定名称的 bean 实例。有些bean是在外部实例化后注册进来的
	Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
			throws BeansException;

	//构造函数
	Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			Constructor<?> ctor, Object... args) throws BeansException;

    //静态工厂或者实例工厂
	Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, Method factoryMethod, Object... args)
			throws BeansException;

}
//源码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
        //非pubic的类无法构建
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
        //有提供者
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
        //工厂方法
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
    
		// Shortcut when re-creating the same bean... 重新构建一个相同的bean时可加快的处理
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
        //之前构建过
		if (resolved) {
			if (autowireNecessary) {
                //自动装配构造函数构建
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
                //默认构造函数构建
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring? 构造器自动装配 
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction? 有优选选择的构造器
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}
        //没有特殊出路就是调用无参的构造器
		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
}
复制代码

1.3 applyMergedBeanDefinitionPostProcessors-实例化后置处理

执行 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition 运行时 合并bean 定义 的后处理器回调接口。例如下面两个将一些运行时的元数据解析合并到beanDefinition中。例如 基于注解依赖注入的元数据 就是在此解析后加入到 BeanDefinition 当中。

CommonAnnotationBeanPostProcessor

处理Java @Resource 、 @PostConstruct 、 @PreDestroy 等元数据

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
	InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
	metadata.checkConfigMembers(beanDefinition);
}
复制代码

AutowiredAnnotationBeanPostProcessor

@Autowire 注解注入依赖逻辑,找到@Autowire对应的注入信息。

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
   metadata.checkConfigMembers(beanDefinition);
}
复制代码

2、 populateBean 填充Bean属性(依赖注入和自动装配)

完成 自动装配 (包含三个注解自动装配)。使用Bean定义中的属性值填充给定的 BeanWrapper 中的Bean实例,包含自动装配( BeanDefinition 中 autowire ) 且执行了 InstantiationAwareBeanPostProcessor 后置处理器(特殊的后置器)的 postProcessAfterInstantiation 和 postProcessPropertyValues ,在 postProcessPropertyValues 中进行了 注解方式的@Resource、@Value、@Autowire的自动装配 等操作。

ps:这里 只关注了自动装配 ,可能有其他功能实现。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		//null值出力
        //2.1实例化后置处理
		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        //2.2 自动装配
		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;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}
复制代码

2.1 实例化后置处理器 InstantiationAwareBeanPostProcessor

在实例化前置的处理时,提到过这个接口,这里就是 实例化后但在设置显式属性或发生自动装配之前的回调 。

2.1.1注解方式的注入

基于 注解形式 的 依赖注入 的都是在此实现的(也是 注解方式的自动装配 ),原理是 反射调用 设置字段值。。

2.1.1.1 处理 @Value 和@ Autowire

AutowiredAnnotationBeanPostProcessor 处理 @Value 和@ Autowire 注解,根据bean的 InjectionMetadata 进行注入。具体实现方式通过 反射 设置字段值。

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
   //获取注入元数据
   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
   try {
      //进行注入
      metadata.inject(bean, beanName, pvs);
   }
   catch (BeanCreationException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
   }
   return pvs;
}

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    //主要处理的字段
	Field field = (Field) this.member;
	Object value;
    //解析需要注入值
	if (this.cached) {
		try {
			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
		}
		catch (NoSuchBeanDefinitionException ex) {
					// Unexpected removal of target bean for cached argument -> re-resolve
			value = resolveFieldValue(field, bean, beanName);
		}
	}
	else {
		value = resolveFieldValue(field, bean, beanName);
	}
    //反射设置值
	if (value != null) {
		ReflectionUtils.makeAccessible(field);
		field.set(bean, value);
	}
}
复制代码

2.1.1.2处理 @Resource

CommonAnnotationBeanPostProcessor 处理Java @Resource 注解,实现方式和上节 AutowiredAnnotationBeanPostProcessor 类似,只不过在解析注入元数据不一样。

2.2 自动装配

Spring支持5种自动装配分别如下:

//AutowireCapableBeanFactory
//不自动装配
int AUTOWIRE_NO = 0;
//按名字自动装配
int AUTOWIRE_BY_NAME = 1;
//按类型自动装配
int AUTOWIRE_BY_TYPE = 2;
//按构造器自动装配
int AUTOWIRE_CONSTRUCTOR = 3;
//自动探测 就是混合自动装配 已经启用更推荐使用注解形式
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
复制代码

自动装配使用方法就是设置 BeanDefinition 的自动装配属性,例如

<bean id="people" class="com.kuang.pojo.Peopel" autowire="byName">
        <property name="name" value="张三"/>
</bean>
复制代码

3、initializeBean初始化Bean

Bean大部分生命周期都在此。分为四大部分:

  1. 执行Aware相关接口
  2. 初始化前置处理
  3. 执行初始化方法
  4. 初始化后置处理
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}
复制代码

3.1 执行Aware接口

Aware 感知到需要的资源已经准备好,可以直接获取。执行顺序如下

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware
  4. EnvironmentAware
  5. EmbeddedValueResolverAware
  6. ResourceLoaderAware
  7. ApplicationEventPublisherAware
  8. MessageSourceAware
  9. ApplicationContextAware
private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}
复制代码

执行Bean后置处理器的 postProcessBeforeInitialization 即特殊的初始化前处理。 ApplicationContextAwareProcessor 后置处理器 它暴露了很多Aware接结口Aware设置顺序如下:

private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
}
复制代码

ImportAware

ImportAwareBeanPostProcessor 处理** ImportAware **接口。即针对于使用 @Import 导入bean时,bean通过该接口可以拿到 Import 元数据。

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
   if (bean instanceof ImportAware) {
      ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
      AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
      if (importingClass != null) {
         ((ImportAware) bean).setImportMetadata(importingClass);
      }
   }
   return bean;
}
复制代码

3.2 Bena后置处理器的初始化前置处理方法

执行初始化的前置处理

3.2.1 @PostConstruct

CommonAnnotationBeanPostProcessor 在 postProcessBeforeInitialization 去 执行 @PostConstruct 指定的初始化方法 

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
   try {
      metadata.invokeInitMethods(bean, beanName);
   }
   catch (InvocationTargetException ex) {
      throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
   }
   return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
			Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
			Collection<LifecycleElement> initMethodsToIterate =
					(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
			if (!initMethodsToIterate.isEmpty()) {
				for (LifecycleElement element : initMethodsToIterate) {
					if (logger.isTraceEnabled()) {
						logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
					}
					element.invoke(target);
				}
			}
		}
复制代码

3.3 invokeInitMethods-执行初始化方法

Bean的指定的一些初始化方法,执行顺序如下:

3.3.1 InitializingBean.afterPropertiesSet

实现了 InitializingBean 接口

3.3.2 invokeCustomInitMethod -自定义初始化方法

​ 用户指定的触发化方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {
   boolean isInitializingBean = (bean instanceof InitializingBean);
   //如果实现InitializingBean接口 则执行afterPropertiesSet方法
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }
   //执行自定义的初始化方法
   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}
复制代码

3.4 Bean后置处理器的初始化后置处理方法

初始化后的后置处理,执行Bean后置处理器的 postProcessAfterInitialization 。例如AOP代理对象的生成就是通过Bean后置处理的初始化后置处理完成的

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
    
    //AOP代理对象生成 AbstractAutoProxyCreator代码片段
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
复制代码

4、销毁

销毁和初始化差不多,每个Bean在创建时都会创建一个 DisposableBeanAdapter 用于销毁Bean执行顺序如下:

4.1 postProcessBeforeDestruction : @PreDestroy

利用 CommonAnnotationBeanPostProcessor 继承了 InitDestroyAnnotationBeanPostProcessor 在 postProcessBeforeDestruction 中执行了 @PreDestroy 指定的销毁方法

@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
   LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
   try {
      metadata.invokeDestroyMethods(bean, beanName);
   }
   catch (InvocationTargetException ex) {
      String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
      if (logger.isDebugEnabled()) {
         logger.warn(msg, ex.getTargetException());
      }
      else {
         logger.warn(msg + ": " + ex.getTargetException());
      }
   }
   catch (Throwable ex) {
      logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
   }
复制代码

4.2 DisposableBean.destroy

bean实现 DisposableBean 即可时在销毁时执行 destroy() 方法

4.3 invokeCustomDestroyMethod -自定义销毁方法

用户指定的销毁方法

@Override
public void destroyBean(Object existingBean) {
   new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
}
public void destroy() {
        //1、postProcessBeforeDestruction
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            //执行销毁Aware相关的后置处理器的postProcessBeforeDestruction
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}
        //2、DisposableBean
		if (this.invokeDisposableBean) {
		  //日志打印
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((DisposableBean) this.bean).destroy();
						return null;
					}, this.acc);
				}
				else {
					((DisposableBean) this.bean).destroy();
				}
			}
			catch (Throwable ex) {
			  //异常处理
			}
		}
        //自定义销毁方法
		if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
			if (methodToInvoke != null) {
				invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
			}
		}
	}
复制代码

三、Bean延迟加载

根据上节的源码分析,Beanfactory初始化( finishBeanFactoryInitialization )时会创建 非懒加载单例 Bean,且由 getBean 方法去创建一个Bean。所以对于 懒加载 的Bean也是由** getBean **获取,依赖注入也是在Bean后置处理器中通过 getBean 去获取依赖的Bean。在 doGetBean ( getBean 调用)中如果Bean不存在会创建一个新的Bean( createBean )。 所以一个懒加载被一个非拦截加载的Bean所依赖,此时拦截bean还是会在启动流程中实例化 。

四、Bean循环依赖

循环依赖是指两个Bean之间互相依赖的导致循环创建问题。Spring提供了三级缓存来解决循环依赖问题。由于Bean生命周期 很长 ,所以可以调用构造器后立即 暴露引用 (放入缓冲中,下次获取则直接从缓存中获取)那么不需要等Bean完全初始化便可使用。

首先对于 原型Bean的循环依赖 是无法解决的,因为原型Bean每次获取都是创建新Bean是不能放入缓存中的。其次 构造器注入 的循环依赖无法解决,因为无法先构造而。

对应单例Bean ,Spring在 getBean 时先尝试从缓存中获取,获取不到再去 createBean 。根据源码我们可以看到缓存分三级,依次从这些缓存中获取。

public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   //从一级缓存中获取
   Object singletonObject = this.singletonObjects.get(beanName);
   //如果一级缓存中没有且单例Bean是在创建中
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         //从二级缓存中获取
         singletonObject = this.earlySingletonObjects.get(beanName);
          //二级缓存中没有 且允许提前使用引用
         if (singletonObject == null && allowEarlyReference) {
             //从三级缓存中获取
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
                //获得Bean 引用
               singletonObject = singletonFactory.getObject();
               //升级到二级缓存 
               this.earlySingletonObjects.put(beanName, singletonObject);
                //删除三级缓存
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}
复制代码

1、一级缓存-singletonObjects

一级缓存中是 完整 的Bean实例,是直接可以使用的,也叫单例池。

//一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
复制代码

AbstractBeanFactory.doGetBean 中获取或者创建Bean,如果是新的 Bean 则加入一级缓存,于此 同时 会 删除 二、三级缓存。 createBean 方法完成意味着Bean走完了生命周期,此时的Bean是完整的。

// Create bean instance.
if (mbd.isSingleton()) {
   // 
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

   //创建新的Bean singletonFactory为上面lambda表达式即通过createBean创建新的
    try {
		singletonObject = singletonFactory.getObject();
		newSingleton = true;
	}
    //是新的Bean
	if (newSingleton) {
		addSingleton(beanName, singletonObject);
	}
//加入一级缓存
protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
}
复制代码

2、二级缓存-earlySingletonObjects

二级缓存存放的是 早期 的Bean(可能是非完整的bean), getSingleton 中会依次遍历这三级缓存,如果是在 三级缓存 中则通过对应的 ObjectFactory (在此对)获得 Bean , 并升级到二级缓存 中。

复制代码

3、三级缓存-singletonFactories

在创建Bean时如果发现是单例Bean且允许提前暴露引用则加入三级缓存。三级缓存存储的是Bean对应的** ObjectFactory **即Bean的工厂,其逻辑是通过在 getObject 中调用 getEarlyBeanReference (它是Spring预留的扩展点通过 SmartInstantiationAwareBeanPostProcessor 对其扩展)。三级缓存的目的是解决存在aop代理时提前触发代理对象的生成。

/** 三级缓存 Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//--------------------------------------------------------------
//doCreateBean方法中  在此代码块之前是创建Bean实例createBeanInstance方法,
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//是单例且允许循环依赖引用以及当前Bean正在创建中则 表示可以提前暴露引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   //加入三级缓存
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}   
   //加入三级缓存
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
        //注意synchronized
		synchronized (this.singletonObjects) {
            //线程安全所以看看其他有没有创建完成
			if (!this.singletonObjects.containsKey(beanName)) {
                 //加入三级缓存
				this.singletonFactories.put(beanName, singletonFactory);
                //删除二级缓存
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}
复制代码

getEarlyBeanReference

getEarlyBeanReference 是Spring预留的 扩展点 -针对获取 Bean提前暴露的引用 的 一次性扩展 操作,通过 SmartInstantiationAwareBeanPostProcessor 后置处理器回调 getEarlyBeanReference 方法对其扩展。例如为了解决存在AOP时的循环依赖而提前触发AOP代理对象生成。

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}
复制代码

4、为什么要三级缓存?

通过原理分析,一般情况我们只需要二级缓存即用另一个缓存提前暴露引用(构造后)便可解决循环依赖的问题,但是 Spring AOP会生成代理对象 也就是会修改引用是不能直接用提前暴露的引用的。利用三级缓存 预留扩展点 ,三级缓存获取时对暴露的Bean引用做 一次性 的处理-存在 AOP时是需要提前触发生成代理对象然后暴露出去 。因为代理对象的生成是在bean后置处理器中的后置处理完成的,而Bean属性填充等其他方式依赖其他Bean是在其前面的(也就是循环依赖是在前面),所以需要提前触发才能解决此循环依赖问题。

5、注意一级缓存是ConcurrentHashMap其他两个缓存是HashMap

相关文章:

  • 斜率优化dp
  • 前端开发常用网站整理
  • 直流有刷电机电流采集基于STM32F302R8+X-NUCLEO-IHM07M1
  • 27_GitGitHub
  • 微信公众号在线查题功能系统使用
  • WPS JS宏示例-批量添加链接
  • Java核心——面向对象编程(上)包-继承-多态
  • Ambari自动部署Hadoop集群实战
  • 33.0、C语言——C语言预处理(1) - 翻译环境详解
  • java-php-python-springboot网上订餐系统计算机毕业设计
  • 【VUE项目实战】66、上线-通过node创建Web服务器
  • About 9.25 This Week
  • 三、基本命令
  • MySQL中select ... for update会锁表还是锁行?
  • 计算机毕业设计选题 SSM大学生企业推荐系统(含源码+论文)
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • css系列之关于字体的事
  • C学习-枚举(九)
  • Js基础知识(一) - 变量
  • nfs客户端进程变D,延伸linux的lock
  • Spring声明式事务管理之一:五大属性分析
  • tab.js分享及浏览器兼容性问题汇总
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 计算机常识 - 收藏集 - 掘金
  • 开源地图数据可视化库——mapnik
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 使用权重正则化较少模型过拟合
  • 数据可视化之 Sankey 桑基图的实现
  • 为什么要用IPython/Jupyter?
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • Java性能优化之JVM GC(垃圾回收机制)
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (1)STL算法之遍历容器
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2)MFC+openGL单文档框架glFrame
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (20050108)又读《平凡的世界》
  • (3)llvm ir转换过程
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (done) 两个矩阵 “相似” 是什么意思?
  • (分类)KNN算法- 参数调优
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot教学评价 毕业设计 641310
  • (九)信息融合方式简介
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十一)c52学习之旅-动态数码管
  • (四) Graphivz 颜色选择
  • (算法)N皇后问题
  • (转)C#调用WebService 基础
  • (转)memcache、redis缓存
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • ***通过什么方式***网吧