Spring——Spring Bean生命周期原理

摘要

本博文主要是分析Spring IOC源码。帮助大家更好的理解spring ioc的思想与原理。

一、Spring IOC 思想

1.1 Spring IOC 容器

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。Spring IoC 的实现原理:Spring 中的 IoC 的实现原理就是工厂模式加反射机制。

Spring 的 IOC 设计支持以下功能:

  • 依赖注入
  • 依赖检查
  • 自动装配
  • 支持集合
  • 指定初始化方法和销毁方法
  • 支持回调某些方法(但是需要实现 Spring 接口,略有侵入)

其中,最重要的就是依赖注入,从 XML 的配置上说,即 ref 标签。对应 Spring RuntimeBeanReference 对象。对于 IoC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入。在spring的IOC中Bean的生命周期是面试Spring框架必问的考点, 在BeanFactory 接口注释上就描述了, 一个Bean对象从工厂生产到最后消亡的全部过程。我们不看源码其实也可以思考一下, 一个对象重创建到消亡需要做些什么?我们可能会想到首先当然是创建对象, 实例化当然是调用构造函数, 实例化之后, 然后我们需要去做一些初始化的操作, 比如设置一些非构造函数属性的值, 当对象用完了然后就是销毁. 当然Spring Bean不一样因为会存在Bean的依赖, 在初始化之前会多一步属性填充。Spring Bean的生命周期其实也是对象创建的过程, 可以划分为4个阶段和多个扩展点。

1.2 BeanFactory和ApplicationContext是Spring的两大核心接口

都可以当做Spring的容器。 其中ApplicationContext是BeanFactory的子接口。

1.2.1 BeanFactory和ApplicationContext的依赖关系

BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。

ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:

  • 继承MessageSource,因此支持国际化。
  • 统一的资源文件访问方式。
  • 提供在监听器中注册bean的事件。
  • 同时加载多个配置文件。
  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

1.2.2 BeanFactory和ApplicationContext的加载方式

BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

1.2.3 BeanFactory和ApplicationContext的创建方式

BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

1.2.4 BeanFactory和ApplicationContext的注册方式

BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

1.2.5 ApplicationContext 容器实现类

  • FileSystemXmlApplicationContext :从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
  • ClassPathXmlApplicationContext:从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
  • WebXmlApplicationContext:加载一个XML文件,此文件定义了一个WEB应用的所有bean。

1.3 Spring IOC核心组件

1.3.1 Resource 体系

org.springframework.core.io.Resource,对资源的抽象。它的每一个实现类都代表了一种资源的访问策略,如 ClassPathResource、RLResource、FileSystemResource 等。

1.3.2 BeanDefinition 体系

org.springframework.beans.factory.config.BeanDefinition ,用来描述 Spring 中的 Bean 对象。

1.3.3 BeanDefinitionReader 体系

org.springframework.beans.factory.support.BeanDefinitionReader 的作用是读取 Spring 的配置文件的内容,并将其转换成 Ioc 容器内部的数据结构 :BeanDefinition 。

1.3.4 BeanFactory 体系

org.springframework.beans.factory.BeanFactory,是一个非常纯粹的 bean 容器,它是 IoC 必备的数据结构,其中 BeanDefinition 是它的基本结构。BeanFactory 内部维护着一个BeanDefinition map ,并可根据 BeanDefinition 的描述进行 bean 的创建和管理。

public interface BeanFactory {

   String FACTORY_BEAN_PREFIX = "&";

   // 根据 bean的名字,获取在IOC容器中得到bean实例
   Object getBean(String name) throws BeansException;

   // 根据 bean的名字和Class类型来得到 bean实例,增加了类型安全验证机制。
   <T> T getBean(String name, Class<T> requiredType) throws BeansException;

   Object getBean(String name, Object... args) throws BeansException;

   <T> T getBean(Class<T> requiredType) throws BeansException;

   <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
   
   <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

   <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
   
   boolean containsBean(String name);
 
   // 根据 bean名字得到bean实例,并同时判断这个 bean是不是单例
   boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
   
   boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
   
   boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

   boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

   @Nullable
   Class<?> getType(String name) throws NoSuchBeanDefinitionException;
  
   @Nullable
   Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

   String[] getAliases(String name);

}

BeanFactory 有三个重要的子类:

  • ListableBeanFactory:表示这些 Bean是可列表化的
  • HierarchicalBeanFactory:表示的是这些 Bean是有继承关系的
  • AutowireCapableBeanFactory:定义Bean的自动装配规则

类 DefaultListableBeanFactory,它实现了所有的接口。

1.4 Spring Bean的生命周期 四个阶段

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

源码分析: 前三个阶段的源码, 都在 AbstractAutowireCapableBeanFactor,doCreateBean 方法实现的。createBeanInstance 实例化。

populateBean 属性注入和initializeBean 初始化Bean方法

上面实例化Bean的方法是在getBean()方法中调用的, 而getBean是在finishBeanFactoryInitialization方法中调用的,用来实例化单例非懒加载Bean。销毁Bean阶段: 是在容器关闭时调用的,详见 ConfigurableApplicationContext#close()。

二、Spring IOC源码分析

2.1 spring对象创建的示例

// 定义接口
public interface MessageService {
   
   String send();
}

// 定义实现类
public class MessageServiceImpl implements MessageService {
   @Override
   public String send() {
      return "你好,庄小焱";
   }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="messageService" class="com.zhuangxiaoyan.spring.demo.impl.MessageServiceImpl"/>
</beans>
public class App {

   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("classpath:MessageBean.xml");

      System.out.println("context start success");

      // 从 context 中取出我们的 Bean,控制反转将创建对象操作交给Spring 不需要自己在new对象
      MessageService messageService = context.getBean(MessageService.class);
      // 这句将输出: 你好,庄小焱
      System.out.println(messageService.send());

   }
}

ClassPathXmlApplicationContext构造函数

public ClassPathXmlApplicationContext(
      String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
      throws BeansException {

   super(parent);
   // 根据提供的路径,处理成配置文件
   setConfigLocations(configLocations);
   if (refresh) {
      // 核心方法
      refresh();
   }
}

获取资源加载器 (AbstractApplicationContext)

public abstract class AbstractApplicationContext extends DefaultResourceLoader
      implements ConfigurableApplicationContext {
      
    static {
       // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
       // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
       ContextClosedEvent.class.getName();
    }

    public AbstractApplicationContext(@Nullable ApplicationContext parent) {
       this();
       setParent(parent);
    }

    public AbstractApplicationContext() {
       // 获取一个Spring reource的加载器
       this.resourcePatternResolver = getResourcePatternResolver();
    } 
     // ....
}

Spring资源加载器 AbstractApplicationContext#getResourcePatternResolver

/**
* Create a new PathMatchingResourcePatternResolver.
* <p>ClassLoader access will happen via the thread context class loader.
* @param resourceLoader the ResourceLoader to load root directories and
* actual resources with
*/
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
	Assert.notNull(resourceLoader, "ResourceLoader must not be null");
	this.resourceLoader = resourceLoader;
}

解析配置路径 AbstractRefreshableConfigApplicationContext。获取到资源加载器后, 再调用父类 AbstractRefreshableConfigApplicationContext 的 setConfigLocations() 方法设定位配置文件的路径信息。

/**
* 处理单个资源文件
* Set the config locations for this application context in init-param style,
* i.e. with distinct locations separated by commas, semicolons or whitespace.
* <p>If not set, the implementation may use a default as appropriate.
*/
public void setConfigLocation(String location) {
	setConfigLocations(StringUtils.tokenizeToStringArray(location, CONFIG_LOCATION_DELIMITERS));
}

/**
* 处理多个资源文件
* Set the config locations for this application context.
* <p>If not set, the implementation may use a default as appropriate.
*/
public void setConfigLocations(@Nullable String... locations) {
	if (locations != null) {
		Assert.noNullElements(locations, "Config locations must not be null");
		this.configLocations = new String[locations.length];
		for (int i = 0; i < locations.length; i++) {
			this.configLocations[i] = resolvePath(locations[i]).trim();
		}
	}
	else {
		this.configLocations = null;
	}
}

2.2 spring IOC核心源码分析AbstractApplicationContext

refresh()函数:Spring IOC容器对bean的装载是从refresh方法开始的,refresh()是一个模板方法,规定了IOC 容器的启动流程, 当然也定义了一些钩子函数,交给子类去实现。

refresh()方法主要为 IOC 容器 Bean 的生命周期管理提供条件,整个 refresh() 中ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() 。这句以后代码的都是注册容器的信息源和生命周期事件,我们前面说的载入就是从这句代码开始启动。Spring IOC容器载入Bean 配置信息是从其子类容器的 refreshBeanFactory() 方法启动。

	@Override
	/**
	 * @description Spring 的核心函数 主要为 IOC 容器 Bean 的生命周期管理提供条件
	  * @param:
	 * @date: 2022/4/22 21:32
	 * @return: void
	 * @author: xjl
	*/
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 1. 准备工作,记录容器启动时间,标记已启动状态
			prepareRefresh();

			// 2.告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3.为BeanFactory配置处理器,例如类加载器、事件处理器等
			prepareBeanFactory(beanFactory);

			try {
				//4. 前置处理器
				postProcessBeanFactory(beanFactory);

				// 5.调用所有注册的BeanFactoryPostProcessor的Bean
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6. 为BeanFactory注册BeanPost事件处理器, BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
				registerBeanPostProcessors(beanFactory);

				//7.初始化信息源,和国际化相关.
				initMessageSource();

				// 8.初始化容器事件传播器
				initApplicationEventMulticaster();

				// 9.调用子类的某些特殊Bean初始化方法
				onRefresh();

				// 10.为事件传播器注册事件监听器.
				registerListeners();

				// 11.初始化所有剩余的单例Bean
				finishBeanFactoryInitialization(beanFactory);

				// 12.初始化容器的生命周期事件处理器,并发布容器的生命周期事件。
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 13.销毁已创建的Bean
				destroyBeans();

				// 14.取消refresh操作,重置容器的同步标识。
				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...
				// 15.重设公共缓存
				resetCommonCaches();
			}
		}
	}

prepareRefresh

	/**
	 * @description 准备此上下文以进行刷新、设置其启动日期和活动标志以及执行任何属性源的初始化。
	  * @param: 
	 * @date: 2022/4/24 9:09
	 * @return: void
	 * @author: xjl
	*/
	protected void prepareRefresh() {
		// Switch to active.
		// 设置启动时间,启动标识
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

AbstractRefreshableApplicationContext,RefreshBeanFactory 创建容器

/**
* 此实现执行此上下文的底层 bean 工厂的实际刷新,关闭先前的 bean 工厂(如果有)并为上下文生命周期的下一阶段初始化一个新的 bean 工厂。
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
	// 如果已经有容器,销毁容器中的bean,关闭容器
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
		// 创建IOC容器
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		// 自定义IOC容器,如设置启动参数,开启注解的自动装配等。
		customizeBeanFactory(beanFactory);
		// 装载Bean的定义
		// 委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器 loadBeanDefinitions(beanFactory);
		loadBeanDefinitions(beanFactory);
		this.beanFactory = beanFactory;
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}

AbstractXmlApplicationContext#loadBeanDefinitions(beanFactory)

	/**
	 * 通过 XmlBeanDefinitionReader 加载 bean 定义。
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 创建XmlBeanDefinitionReader。
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 为Bean读取器设置Spring资源加载器。
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制。
		initBeanDefinitionReader(beanDefinitionReader);
		// Bean读取器真正实现加载的方法。
		loadBeanDefinitions(beanDefinitionReader);
	}

initBeanDefinitionReader

protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
   reader.setValidating(this.validating);
}

loadBeanDefinitions

	/**
	 * Xml Bean读取器加载Bean定义资源
	 * Load the bean definitions with the given XmlBeanDefinitionReader.
	 * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
	 * method; hence this method is just supposed to load and/or register bean definitions.
	 * @param reader the XmlBeanDefinitionReader to use
	 * @throws BeansException in case of bean registration errors
	 * @throws IOException if the required XML document isn't found
	 * @see #refreshBeanFactory
	 * @see #getConfigLocations
	 * @see #getResources
	 * @see #getResourcePatternResolver
	 */
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		// 获取Bean定义资源的定位
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			// Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			// Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源
			reader.loadBeanDefinitions(configLocations);
		}
	}

prepareBeanFactory(beanFactory)

这个方法不难理解,定了一堆处理器,比如类加载器,事件处理器等等。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
   // ....
}

postProcessBeanFactory(beanFactory) 前置处理器

spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

invokeBeanFactoryPostProcessors

为BeanFactory注册BeanPost事件处理器, BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件,核心方法后面还会详细去介绍。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

registerBeanPostProcessors(beanFactory)

为BeanFactory注册BeanPost事件处理器, BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件.

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

initMessageSource

//7.初始化信息源,和国际化相关.

initMessageSource();

initApplicationEventMulticaster

初始化容器事件传播器.

	/**
	 * 初始化 ApplicationEventMulticaster。
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

onRefresh()

调用子类的某些特殊Bean初始化方法, 主要和web相关

registerListeners

为事件传播器注册事件监听器.

	/**
	 * 添加实现 ApplicationListener 作为侦听器的 bean。
	 * 不影响其他监听器,可以添加而不是bean。
	 */
	protected void registerListeners() {
		//手动注册的监听器绑定到广播器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean
		// 未初始化让后处理器适用于他们!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 先发布早期的监听器
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

finishBeanFactoryInitialization

初始化所有剩余的单例Bean

	/**
	 * 完成这个上下文的bean工厂的初始化,初始化所有剩余的单例 bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 为此上下文初始化转换服务。
		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();
	}

finishRefresh

初始化容器的生命周期事件处理器,并发布容器的生命周期事件。

	/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	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);
	}

2.3 ObtainFreshBeanFactory

告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动。

该方法的主要作用是将bean定义beandefinition加载到BeanFactory中。

  1. 该方法会解析所有 Spring 配置文件(application-**.xml),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。

  2. 常见的,如果解析到<context:component-scan base-package="" /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的配置也同样封装成 BeanDefinition,加载到 BeanFactory 中。

三个重要的缓存:

  • BeanDefinitionNames缓存:所有被加载到 BeanFactory 中的bean的beanName 集合。
  • BeanDefinitionMap缓存:所有被加载到 BeanFactory 中的bean的beanName和 BeanDefinition 映射。
  • aliasMap缓存:所有被加载到 BeanFactory 中的bean的beanName和别名映射。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   // 1. 刷新BeanFactory,有子类 AbstractRefreshableApplicationContext 实现
   refreshBeanFactory();
   // 2. 拿到刷新后的BeanFactory
   return getBeanFactory();
}

refreshBeanFactory():刷新BeanFactory,有子类 AbstractRefreshableApplicationContext 实现。

基本流程

  1. 获取 resourceLoader
  2. 判断 resourceLoader 是否为 ResourcePatternResolver 的实例
    2.1 根据路径拿到该路径下所有符合的配置文件,并封装成 Resource
    2.2 根据 Resource,加载 bean 定义
@Override
protected final void refreshBeanFactory() throws BeansException {
   // 1. 判断是否存在BeanFactory, 如果存在先销毁,关闭该BeanFactory
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      // 2. 创建新的BeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      // 3. 加载bean定义, 由XmlWebApplicationConetxt实现
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

XmlWebApplicationContext#loadBeanDefinitions

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   // 1. 为BeanFactory 创建 XmlBeanDefinitionReader
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   // 2. 使用此上下文资源加载环境配置
   beanDefinitionReader.setEnvironment(getEnvironment());
   // setResourceLoader 为 XmlBeanDefinitionReader
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);
   // 3. 加载bean定义
   loadBeanDefinitions(beanDefinitionReader);
}

XmlWebApplicationContext#loadBeanDefinitions

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
   // 1. 获取配置文件路径
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      for (String configLocation : configLocations) {
         // 2. 根据配置文件路径加载Bean定义
         reader.loadBeanDefinitions(configLocation);
      }
   }
}

AbstractBeanDefinitionReader#loadBeanDefinitions

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
   // 1. 获取 resourceLoader, 这边为 XmlWebApplicationContext
   ResourceLoader resourceLoader = getResourceLoader();
   if (resourceLoader == null) {
      throw new BeanDefinitionStoreException(
            "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
   }

   // 2. 判断 resourceLoader 是否为 ResourcePatternResolver 的实例
   if (resourceLoader instanceof ResourcePatternResolver) {
      // Resource pattern matching available.
      try {
         // 2.1 根据路径查找到该路径下面所有符合的配置文件,并封装成Resource
         Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
         // 2.2 根据Resource定义,加载Bean定义
         int count = loadBeanDefinitions(resources);
         if (actualResources != null) {
            Collections.addAll(actualResources, resources);
         }
         if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
         }
         return count;
      }
      catch (IOException ex) {
         throw new BeanDefinitionStoreException(
               "Could not resolve bean definition resource pattern [" + location + "]", ex);
      }
   }
   else {
      // Can only load single resources by absolute URL.
      // 3. 只能通过绝对URL路径加载单个资源
      Resource resource = resourceLoader.getResource(location);
      // 3.1 根据 resource 加载bean定义
      int count = loadBeanDefinitions(resource);
      if (actualResources != null) {
         actualResources.add(resource);
      }
      if (logger.isTraceEnabled()) {
         logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
      }
      return count;
   }
}

AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)

@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
   Assert.notNull(resources, "Resource array must not be null");
   int count = 0;
   // 1. 遍历所有的Resource
   for (Resource resource : resources) {
      // 2. 根据 Resource 加载Bean定义,XmlBeanDefinitionReader实现
      count += loadBeanDefinitions(resource);
   }
   return count;
}

根据 Resource 加载 bean 定义,由 XmlBeanDefinitionReader 实现

XmlBeanDefinitionReader#loadBeanDefinitions

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
   Assert.notNull(encodedResource, "EncodedResource must not be null");
   if (logger.isTraceEnabled()) {
      logger.trace("Loading XML bean definitions from " + encodedResource);
   }

   // 1. 当前正在加载的EncodedResource
   Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

   // 2. 将当前的 encodedResource 添加到 currentResources
   if (!currentResources.add(encodedResource)) {
      throw new BeanDefinitionStoreException(
            "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
   }
   // 3. 拿到 encodedResource 的 inputStream
   try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
      // 4. 将 inputStream 封装成 org.xml.sax.InputSource
      InputSource inputSource = new InputSource(inputStream);
      if (encodedResource.getEncoding() != null) {
         inputSource.setEncoding(encodedResource.getEncoding());
      }
      // 5. 加载bean定义, 真正加载bean定义的do方法
      return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
   }
   catch (IOException ex) {
      throw new BeanDefinitionStoreException(
            "IOException parsing XML document from " + encodedResource.getResource(), ex);
   }
   finally {
      currentResources.remove(encodedResource);
      if (currentResources.isEmpty()) {
         this.resourcesCurrentlyBeingLoaded.remove();
      }
   }
}

AbstractBeanDefinitionReader#doLoadBeanDefinitions

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
      throws BeanDefinitionStoreException {

   try {
      // 1. 根据imputResource和resource 加载XML文件并封装Document
      Document doc = doLoadDocument(inputSource, resource);
      // 2. 根据返回的Document 注册Bean信息
      int count = registerBeanDefinitions(doc, resource);
      if (logger.isDebugEnabled()) {
         logger.debug("Loaded " + count + " bean definitions from " + resource);
      }
      return count;
   }
   catch (BeanDefinitionStoreException ex) {
      // ....
   }
}

AbstractBeanDefinitionReader#doLoadDocument

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
// 1. 获取XML文件的验证方式
// 2. 加载XML文件并得到 Document
   return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
         getValidationModeForResource(resource), isNamespaceAware());
}

getValidationModeForResource

protected int getValidationModeForResource(Resource resource) {
   int validationModeToUse = getValidationMode();
   if (validationModeToUse != VALIDATION_AUTO) {
      return validationModeToUse;
   }
   int detectedMode = detectValidationMode(resource);
   if (detectedMode != VALIDATION_AUTO) {
      return detectedMode;
   }
   // Hmm, we didn't get a clear indication... Let's assume XSD,
   // since apparently no DTD declaration has been found up until
   // detection stopped (before finding the document's root tag).
   return VALIDATION_XSD;
}

loadDocument

@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
      ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
   // 1. 创建DocumentBuilderFactory
   DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
   if (logger.isTraceEnabled()) {
      logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
   }
   // 2. 通过 DocumentBuilderFactory 创建 DocumentBuilder
   DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
   // 3. 使用DocumentBuilder解析并返回Document对象
   return builder.parse(inputSource);
}

registerBeanDefinitions

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   // 1. 使用DefaultBeanDefinitionDocumentReader 实例化 BeanDefinitionDocumentReader
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   // 2. 记录统计BeanDifinition加载的个数
   int countBefore = getRegistry().getBeanDefinitionCount();
   // 3. createReaderContext, 根据resource创建XmlReaderContext
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   return getRegistry().getBeanDefinitionCount() - countBefore;
}

createReaderContext

  • 根据 resource 构建一个 XmlReaderContext,用于存放解析时会用到的一些上下文信
  • 其中 namespaceHandlerResolver 会创建默认的 DefaultNamespaceHandlerResolver,DefaultNamespaceHandlerResolver的handlerMappingsLocation 属性会使用默认的值 “META-INF/spring.handlers”,并且这边有个重要的属性 handlerMappings,handlerMappings 用于存放命名空间和该命名空间handler类的映射.
public XmlReaderContext createReaderContext(Resource resource) {
   return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
         this.sourceExtractor, this, getNamespaceHandlerResolver());
}

public NamespaceHandlerResolver getNamespaceHandlerResolver() {
   if (this.namespaceHandlerResolver == null) {
      this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
   }
   return this.namespaceHandlerResolver;
}


protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
   ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
   return new DefaultNamespaceHandlerResolver(cl);
}

registerBeanDefinitions

protected void doRegisterBeanDefinitions(Element root) {
   
   BeanDefinitionParserDelegate parent = this.delegate;
   // 构件BeanDefinitionParserDelegate
   this.delegate = createDelegate(getReaderContext(), root, parent);
   // 1. 校验Root节点命名空间是否是默认的命名空间
   if (this.delegate.isDefaultNamespace(root)) {
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         // We cannot use Profiles.of(...) since profile expressions are not supported
         // in XML config. See SPR-12458 for details.
         // 2. 校验profile
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            if (logger.isDebugEnabled()) {
               logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                     "] not matching: " + getReaderContext().getResource());
            }
            return;
         }
      }
   }

   preProcessXml(root);
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root);

   this.delegate = parent;
}

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它.(这个也是Spring生态如此火爆的原因, 提供了一系列的扩展点,方便第三方的框架去集成)。BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。

refresh#invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   // 1. getBeanFactoryPostProcessors() 获取当前应用上下文
   // 2. invokeBeanFactoryPostProcessors 实例化并调用所有已注册的BeanFactoryPostProcessors
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

getBeanFactoryPostProcessors

// 获取上下文已经注册的beanFactoryPostProcessors
// 在默认情况下,this.beanFactoryPostProcessors 是返回空的。
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
   return this.beanFactoryPostProcessors;
}

getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。

两种方法

  1. 注解的方式,将自己实现的beanFactoryPostProcessor注册到beanFactory中.
  2. 新建一个 ApplicationContextInitializer 的实现类 SpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑.
// 注解的方式, 实现BeanFactoryPostProcessor
@Component
public class MyBeanPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("this is my BeanFactoryPostProcessor");
   }
}

// 不需要component注解
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("this is my BeanFactoryPostProcessor2");
   }
}

// 通过ApplicationContextInitializer实现类添加BeanFactoryPostProcessor
public class SpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
   @Override
   public void initialize(ConfigurableApplicationContext applicationContext) {
      MyBeanFactoryPostProcessor myBeanFactoryPostProcessor = new MyBeanFactoryPostProcessor();
      applicationContext.addBeanFactoryPostProcessor(myBeanFactoryPostProcessor);
   }
}

invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   Set<String> processedBeans = new HashSet<>();

   // 1. 判断beanFactory 是否是 BeanDefinitionRegistry
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      // 用于存放普通的 BeanFactoryPostProcessor
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      // 用于存放 BeanDefinitionRegistryPostProcessor
      // mybatis 就是用BeanDefinitionRegistryPostProcessor后置处理器来实现bean和beandefinition的
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      // 2. 遍历所有的beanFactoryPostProcessors, 将普通的BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor 分别处理
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }

      // 保存本次要执行的 BeanDefinitionRegistryPostProcessor
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      // 3. 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors实现类
      // 3.1 找出BeanDefinitionRegistryPostProcessor 接口Bean的BeanName
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      // 3.2 遍历 postProcessorNames
      for (String ppName : postProcessorNames) {
         // 3.3 校验是否实现了 PriorityOrdered 接口
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 3.4 获取 ppName 对应的Bean实例, 添加到currentRegistryProcessors 中
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            // 3.5 防重
            processedBeans.add(ppName);
         }
      }
      // 3.6 排序(根据是否实现了 PriorityOrdered, Ordered接口和order值来排序)
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      // 3.7 添加到 registryProcessors
      registryProcessors.addAll(currentRegistryProcessors);
      // 3.8 遍历currentRegistryProcessors 并执行BeanDefinitionRegistryPostProcessor
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      // 3.9 清空
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      // 4. 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类
      // 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         // 校验是否实现了 Ordered 接口
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      // 4.2 遍历currentRegistryProcessors并执行BeanDefinitionRegistryPostProcessor
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      // 5. 最后,调用所有剩下的 BeanDefinitionRegistryPostProcessors
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      // 6. 调用所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      // 7. 最后调用入参普通 regularPostProcessors的 postProcessBeanFactory 方法
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   // 开始处理容器中的 BeanFactoryPostProcessor, 流程其实和上面类似
   // 8. 找出BeanFactoryPostProcessor 接口的实现类
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

2.4 registerBeanPostProcessors

invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理 BeanPostProcessor 接口。BeanFactoryPostProcessor 和 BeanPostProcessor区别:

  • BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。
  • BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后。

比如AOP生成代理的功能,就是在被代理类实例化之后去生成代理对象的.

registerBeanPostProcessors 会注册所有的 BeanPostProcessor, 将所有实现了BeanPostProcessor 的类加载到BeanFactory中。BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

registerBeanPostProcessors

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   // 1. 找出所有实现 BeanPostProcessor 接口的类
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   // BeanPostProcessor 计数
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   // 2. 添加 BeanPostProcessorChecker , 主要用于记录信息到BeanFactory中
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   // 3. 定义不同的变量用于区分实现PriorityOrdered, Ordered 接口的 BeanPostProcessor 和普通的BeanPostProcessor
   // 3.1 priorityOrderedPostProcessors 存储实现PriorityOrdered 接口的BeanPostProcessor
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 3.2 internalPostProcessors 存储Spring内部的BeanPostProcessor
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   // 3.3 orderedPostProcessorNames 存储实现Ordered接口BeanPostProcessor 的Name
   List<String> orderedPostProcessorNames = new ArrayList<>();
   // 3.4 存储普通的BeanPostProcessor 的BeanName
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   // 4. 遍历postProcessorNames
   for (String ppName : postProcessorNames) {
      // 4.1 实现PriorityOrdered 接口的BeanPostProcessor 处理
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         // 4.2 如果 pp对应Bean实例也实现了 MergedBeanDefinitionPostProcessor接口,则添加到internalPostProcessors
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         // 4.3 实现了Ordered接口, 添加到 orderedPostProcessorNames
         orderedPostProcessorNames.add(ppName);
      }
      else {
         // 4.4 普通的 nonOrderedPostProcessorNames
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
   // 5. 首先, 注册实现了PriorityOrdered 接口的BeanPostProcessors
   // 5.1 排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   // 5.2 注册 registerBeanPostProcessors
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   // 6. 接下来, 注册实现 Ordered 接口的BeanPostProcessors
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      // 6.1 拿到ppName对应的 BeanPostProcessor
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      // 6.2 添加到orderedPostProcessors 准备执行注册
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         // 6.3 如果pp实例也实现了 MergedBeanDefinitionPostProcessor接口, 添加到 internalPostProcessors
         internalPostProcessors.add(pp);
      }
   }
   // 6.4 排序
   sortPostProcessors(orderedPostProcessors, beanFactory);
   // 6.5 注册 orderedPostProcessors
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   // 7. 注册普通的 BeanPostProcessors
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   // 8. 最后,重新注册内部 internalPostProcessors,(相当于移动到链表的末尾)
   // 8.1 排序
   sortPostProcessors(internalPostProcessors, beanFactory);
   // 8.2 注册 internalPostProcessors
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   // 9. 重新注册 ApplicationListenerDetector,主要目的是移动到处理链的末尾
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

registerBeanPostProcessors

/**
 * Register the given BeanPostProcessor beans.
 */
private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

   for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
   }
}

beanFactory#addBeanPostProcessor

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
   // Remove from old position, if any
   // 如果存在则移除
   this.beanPostProcessors.remove(beanPostProcessor);
   // Track whether it is instantiation/destruction aware
   // 设置标识 hasInstantiationAwareBeanPostProcessors
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   // 设置标识 hasDestructionAwareBeanPostProcessors
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
   }
   // Add to end of list
   // beanPostProcessor 添加到链表中
   this.beanPostProcessors.add(beanPostProcessor);
}

2.5 BeanFactoryPostProcessor测试实例

定义MyPostProcessorBean实现 BeanPostProcessor 接口

package com.zhuangxiaoyan.helloworld.Entity;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;

/**
 * @Classname MyBeanPostProcessor
 * @Description TODO
 * @Date 2022/4/24 11:52
 * @Created by xjl
 */
public class MyPostProcessorBean implements BeanPostProcessor, PriorityOrdered {
    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean 实例化之前…………"+beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean 实例化之后…………"+beanName);
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

定义User对象, 通过Configuration 定义Bean

package com.zhuangxiaoyan.helloworld.Entity;

/**
 * @Classname User
 * @Description TODO
 * @Date 2022/4/24 11:55
 * @Created by xjl
 */
public class User {
    private String name;

    public User() {
        System.out.println("User 对象实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

定义Bean

package com.zhuangxiaoyan.helloworld.config;

import com.zhuangxiaoyan.helloworld.Entity.MyPostProcessorBean;
import com.zhuangxiaoyan.helloworld.Entity.User;
import org.springframework.context.annotation.Bean;

/**
 * @Classname BeanConfig
 * @Description TODO
 * @Date 2022/4/24 11:55
 * @Created by xjl
 */
public class BeanConfig {
    @Bean
    public User user() {
        return new User();
    }

    @Bean
    public MyPostProcessorBean myPostProcessorBean() {
        return new MyPostProcessorBean();
    }
}

测试与结果

package com.zhuangxiaoyan.helloworld;

import com.zhuangxiaoyan.helloworld.config.BeanConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @Classname BeanPostProcessorTest
 * @Description TODO
 * @Date 2022/4/24 11:58
 * @Created by xjl
 */
public class BeanPostProcessorTest {
    @Test
    public void test() {
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
    }
}

 注意两个比较容易踩的坑

  1. BeanPostProcessor依赖的bean,不会执行BeanPostProcessor的方法
  2. BeanPostProcessor以及依赖的bean无法使用AOP

FactoryBean 和 BeanFactory的区别

BeanFactory 是 Bean 的工厂, ApplicationContext 的父类,IOC 容器的核心,负责生产和管理 Bean 对象。
FactoryBean 是 Bean,可以通过实现 FactoryBean 接口定制实例化 Bean 的逻辑,通过代理一个Bean对象,对方法前后做一些操作。

2.6 finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   // 1. 初始化上下文转换服务
   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.
   // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   // 3. 初始化LoadTimeWeaverAware Bean实例对象
   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.
   // 4. 冻结所有bean定义,因为马上要创建 Bean 实例对象了
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   // 5. 实例化所有剩余(非懒加载)单例对象
   beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons

@Override
public 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.
   // 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   // 2.遍历beanNames,触发所有非懒加载单例bean的初始化
   for (String beanName : beanNames) {
      // 3.获取beanName 对应的 MergedBeanDefinition
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 4.bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 5.判断beanName对应的bean是否为FactoryBean
         if (isFactoryBean(beanName)) {
            // 5.1 通过beanName获取FactoryBean实例
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               // 5.2 判断这个FactoryBean是否希望急切的初始化
               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) {
                  // 5.3 如果希望急切的初始化,则通过beanName获取bean实例
                  getBean(beanName);
               }
            }
         }
         else {
            // 6.如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   // 7.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
   for (String beanName : beanNames) {
      // 7.1 获取beanName对应的bean实例
      Object singletonInstance = getSingleton(beanName);
      // 7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         // 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

getMergedLocalBeanDefinition

MergedBeanDefinition 合并的Bean定义,之所以称为合并Bean定义,是因为存在父子关系.

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
   // Quick check on the concurrent map first, with minimal locking.
   // 先查询缓存有没有
   RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
   if (mbd != null && !mbd.stale) {
      return mbd;
   }
   // 根据 beanName 和 beanName 对应的 BeanDefinition,获取 MergedBeanDefinition
   return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
      throws BeanDefinitionStoreException {
   return getMergedBeanDefinition(beanName, bd, null);
}

getMergedBeanDefinition

protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

   // 1. 枷锁
   synchronized (this.mergedBeanDefinitions) {
      RootBeanDefinition mbd = null;
      RootBeanDefinition previous = null;

      // Check with full lock now in order to enforce the same merged instance.
      // 2.检查beanName对应的MergedBeanDefinition是否存在于缓存中
      if (containingBd == null) {
         mbd = this.mergedBeanDefinitions.get(beanName);
      }

      // 3.如果beanName对应的MergedBeanDefinition不存在于缓存中
      if (mbd == null || mbd.stale) {
         previous = mbd;
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            // 4.如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作
            if (bd instanceof RootBeanDefinition) {
               // 4.1 如果bd的类型为RootBeanDefinition,则直接克隆一个副本
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
               // 4.2 否则,构建一个RootBeanDefinition
               mbd = new RootBeanDefinition(bd);
            }
         }
         else {
            // Child bean definition: needs to be merged with parent.
            // 5.否则,bd存在父定义,需要与父定义合并
            BeanDefinition pbd;
            try {
               // 5.1 获取父定义的beanName
               String parentBeanName = transformedBeanName(bd.getParentName());
               // 5.2 如果父定义的beanName与该bean的beanName不同
               if (!beanName.equals(parentBeanName)) {
                  // 5.3 递归获取父定义的MergedBeanDefinition
                  pbd = getMergedBeanDefinition(parentBeanName);
               }
               else {
                  // 5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
                  BeanFactory parent = getParentBeanFactory();
                  if (parent instanceof ConfigurableBeanFactory) {
                     // 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                     pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                  }
                  else {
                     // 5.6 如果不是,直接抛异常
                     throw new NoSuchBeanDefinitionException(parentBeanName,
                           "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                           "': cannot be resolved without a ConfigurableBeanFactory parent");
                  }
               }
            }
            catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }
            // Deep copy with overridden values.
            // 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
            mbd = new RootBeanDefinition(pbd);
            // 5.8 使用bd覆盖父定义
            mbd.overrideFrom(bd);
         }

         // Set default singleton scope, if not configured before.
         // 6.如果没有配置scope,则设置成默认的singleton
         if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(SCOPE_SINGLETON);
         }

         // A bean contained in a non-singleton bean cannot be a singleton itself.
         // Let's correct this on the fly here, since this might be the result of
         // parent-child merging for the outer bean, in which case the original inner bean
         // definition will not have inherited the merged outer bean's singleton status.
         // 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton
         // 则将mdb的scope设置为containingBd的scope
         if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
            mbd.setScope(containingBd.getScope());
         }

         // Cache the merged bean definition for the time being
         // (it might still get re-merged later on in order to pick up metadata changes)
         // 8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
         if (containingBd == null && isCacheBeanMetadata()) {
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }
      if (previous != null) {
         copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      // 9.返回MergedBeanDefinition
      return mbd;
   }
}

transformedBeanName

将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。

protected String transformedBeanName(String name) {
   return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

// beanName 转换
public static String transformedBeanName(String name) {
   Assert.notNull(name, "'name' must not be null");
   if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
      return name;
   }
   return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
      do {
         beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
      }
      while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
      return beanName;
   });
}

// 将别名解析成真正的beanName
public String canonicalName(String name) {
   String canonicalName = name;
   // Handle aliasing...
   String resolvedName;
   do {
      resolvedName = this.aliasMap.get(canonicalName);
      if (resolvedName != null) {
        canonicalName = resolvedName;
      }
   }
   while (resolvedName != null);
   return canonicalName;
}

getMergedBeanDefinition

父子容器 BeanFactory:在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。

最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
   //1.获取真正的beanName(解析别名)
   String beanName = transformedBeanName(name);
   // Efficiently check whether bean definition exists in this factory.
   // 2.如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // 调用父BeanFactory去获取beanName的MergedBeanDefinition
      return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
   }
   // Resolve merged bean definition locally.
   // 3.在当前BeanFactory中解析beanName的MergedBeanDefinition
   return getMergedLocalBeanDefinition(beanName);
}

isFactoryBean

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
   // 1.获取真正的beanName(去掉&前缀、解析别名)
   String beanName = transformedBeanName(name);
   // 2. 尝试从缓存获取Bean实例对象
   Object beanInstance = getSingleton(beanName, false);
   if (beanInstance != null) {
      // 3.beanInstance存在,则直接判断类型是否为FactoryBean
      return (beanInstance instanceof FactoryBean);
   }
   // No singleton instance found -> check bean definition.
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // No bean definition found in this factory -> delegate to parent.
      // 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory
      // 则调用父BeanFactory判断是否为FactoryBean
      return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
   }
   // 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
   return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

getSingleton

经典的三级缓存代码, 常见面试题目如何解决循环依赖? 为什么要三级缓存,二级缓存是不是就行了等等?

spring内部有三级缓存

  • singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
  • earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例
  • singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // Quick check for existing instance without full singleton lock
   // 1.从单例对象缓存中获取beanName对应的单例对象
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      // 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
         // 3.加锁进行操作
         synchronized (this.singletonObjects) {
            // Consistent creation of early reference within full singleton lock
            // 4.从早期单例对象缓存中获取单例对象(一级缓存)
            // 之所称成为早期单例对象,是因为earlySingletonObjects里的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);
               if (singletonObject == null) {
                  // 6.从单例工厂缓存中获取beanName的单例工厂
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     // 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
                     singletonObject = singletonFactory.getObject();
                     // 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     // 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
                     // 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

isFactoryBean

protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
   Boolean result = mbd.isFactoryBean;
   if (result == null) {
      // 1. 获取beanName对应的Bean实例的类型
      Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
      // 2.返回beanType是否为FactoryBean本身、子类或子接口
      result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
      mbd.isFactoryBean = result;
   }
   return result;
}

predictBeanType

@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
   Class<?> targetType = mbd.getTargetType();
   if (targetType != null) {
      return targetType;
   }
   if (mbd.getFactoryMethodName() != null) {
      return null;
   }
   return resolveBeanClass(mbd, beanName, typesToMatch);
}

finishBeanFactoryInitialization 主要功能普通Bean的创建和初始化. 还有一些非常容易混淆的概念

  1. MergedBeanDefinition 合并BeanDefinition
  2. FactoryBean 和 BeanFactory的区别
  3. 父子容器 BeanFactory
  4. spring内部有三级缓存, singletonObjects, earlySingletonObjects,singletonFactories

三、Spring IOC之Bean实例化

IOC设计要点和设计结构;以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的;容器中存放的是Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap<String, Object>;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等。那么如何从BeanDefinition中实例化Bean对象呢?

3.1 BeanFactory中getBean的思路

上文中我们知道BeanFactory定义了Bean容器的规范,其中包含根据bean的名字, Class类型和参数等来得到bean实例。

// 根据bean的名字和Class类型等来得到bean实例    
Object getBean(String name) throws BeansException;    
Object getBean(String name, Class requiredType) throws BeansException;    
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

上文我们已经分析了IoC初始化的流程,最终的将Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap<String, Object>;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等;

这样我们初步有了实现Object getBean(String name)这个方法的思路:

  • 从beanDefinitionMap通过beanName获得BeanDefinition
  • 从BeanDefinition中获得beanClassName
  • 通过反射初始化beanClassName的实例instance
    • 构造函数从BeanDefinition的getConstructorArgumentValues()方法获取
    • 属性值从BeanDefinition的getPropertyValues()方法获取
  • 返回beanName的实例instance

由于BeanDefinition还有单例的信息,如果是无参构造函数的实例还可以放在一个缓存中,这样下次获取这个单例的实例时只需要从缓存中获取,如果获取不到再通过上述步骤获取。

Spring中getBean的主体思路

BeanFactory实现getBean方法在AbstractBeanFactory中,这个方法重载都是调用doGetBean方法进行实现的:

public Object getBean(String name) throws BeansException {
  return doGetBean(name, null, null, false);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
  return doGetBean(name, requiredType, null, false);
}
public Object getBean(String name, Object... args) throws BeansException {
  return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
    throws BeansException {
  return doGetBean(name, requiredType, args, false);
}
// 参数typeCheckOnly:bean实例是否包含一个类型检查
protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

  // 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
  String beanName = transformedBeanName(name);
  Object beanInstance;

  // Eagerly check singleton cache for manually registered singletons.
  Object sharedInstance = getSingleton(beanName);
  if (sharedInstance != null && args == null) {
    // 无参单例从缓存中获取
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  }

  else {
    // 如果bean实例还在创建中,则直接抛出异常
    if (isPrototypeCurrentlyInCreation(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
    }

    // 如果 bean definition 存在于父的bean工厂中,委派给父Bean工厂获取
    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实例放入alreadyCreated集合里,标识这个bean准备创建了
      markBeanAsCreated(beanName);
    }

    StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
        .tag("beanName", name);
    try {
      if (requiredType != null) {
        beanCreation.tag("beanType", requiredType::toString);
      }
      RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      checkMergedBeanDefinition(mbd, beanName, args);

      // 确保它的依赖也被初始化了.
      String[] dependsOn = mbd.getDependsOn();
      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); // 初始化它依赖的Bean
          }
          catch (NoSuchBeanDefinitionException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
          }
        }
      }

      // 创建Bean实例:单例
      if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
          try {
            // 真正创建bean的方法
            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;
          }
        });
        beanInstance = 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);
        }
        beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
      }
      // 创建Bean实例:根据bean的scope创建
      else {
        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);
            }
          });
          beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
        catch (IllegalStateException ex) {
          throw new ScopeNotActiveException(beanName, scopeName, ex);
        }
      }
    }
    catch (BeansException ex) {
      beanCreation.tag("exception", ex.getClass().toString());
      beanCreation.tag("message", String.valueOf(ex.getMessage()));
      cleanupAfterBeanCreationFailure(beanName);
      throw ex;
    }
    finally {
      beanCreation.end();
    }
  }

  return adaptBeanInstance(name, beanInstance, requiredType);
}

Spring中getBean的主体思路

  • 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
  • 无参单例先从缓存中尝试获取
  • 如果bean实例还在创建中,则直接抛出异常
  • 如果bean definition 存在于父的bean工厂中,委派给父Bean工厂获取
  • 标记这个beanName的实例正在创建
  • 确保它的依赖也被初始化
  • 真正创建
    • 单例时
    • 原型时
    • 根据bean的scope创建

3.2 Spring中Bean的生命周期

Spring 只帮我们管理单例模式 Bean 的完整生命周期,对于 prototype 的 bean ,Spring 在创建好交给使用者之后则不会再管理后续的生命周期。

Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。

而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。

了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。

在 Spring 中,Bean 的生命周期是一个很复杂的执行过程,我们可以利用 Spring 提供的方法定制 Bean 的创建过程。

  • 如果 BeanFactoryPostProcessor 和 Bean 关联, 则调用postProcessBeanFactory方法.(即首先尝试从Bean工厂中获取Bean)
  • 如果 InstantiationAwareBeanPostProcessor 和 Bean 关联,则调用postProcessBeforeInstantiation方法
  • 根据配置情况调用 Bean 构造方法实例化 Bean
  • 利用依赖注入完成 Bean 中所有属性值的配置注入
  • 如果 InstantiationAwareBeanPostProcessor 和 Bean 关联,则调用postProcessAfterInstantiation方法和postProcessProperties
  • 调用xxxAware接口 (上图只是给了几个例子)
    • 第一类Aware接口
      • 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
      • 如果 Bean 实现了 BeanClassLoaderAware 接口,则 Spring 调用 setBeanClassLoader() 方法传入classLoader的引用。
      • 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
    • 第二类Aware接口
      • 如果 Bean 实现了 EnvironmentAware 接口,则 Spring 调用 setEnvironment() 方法传入当前 Environment 实例的引用。
      • 如果 Bean 实现了 EmbeddedValueResolverAware 接口,则 Spring 调用 setEmbeddedValueResolver() 方法传入当前 StringValueResolver 实例的引用。
      • 如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
      • ...
  • 如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
  • 如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。(或者有执行@PostConstruct注解的方法)
  • 如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
  • 如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
  • 如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
  • 如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;(或者有执行@PreDestroy注解的方法)
  • 如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:(结合上图,需要有如下顶层思维)

  • Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
  • Bean级生命周期接口方法: 这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware;当然也包括InitializingBean和DiposableBean这些接口的方法(可以被@PostConstruct和@PreDestroy注解替代)
  • 容器级生命周期接口方法: 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
  • 工厂后处理器接口方法: 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

3.3 Spring如何解决循环依赖问题

Spring只是解决了单例模式下属性依赖的循环问题;Spring为了解决单例的循环依赖问题,使用了三级缓存。

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
 
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
  • 第一层缓存(singletonObjects):单例对象缓存池,已经实例化并且属性赋值,这里的对象是成熟对象
  • 第二层缓存(earlySingletonObjects):单例对象缓存池,已经实例化但尚未属性赋值,这里的对象是半成品对象
  • 第三层缓存(singletonFactories): 单例工厂的缓存
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  // Spring首先从singletonObjects(一级缓存)中尝试获取
  Object singletonObject = this.singletonObjects.get(beanName);
  // 若是获取不到而且对象在建立中,则尝试从earlySingletonObjects(二级缓存)中获取
  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) {
            //若是仍是获取不到而且容许从singletonFactories经过getObject获取,则经过singletonFactory.getObject()(三级缓存)获取
              singletonObject = singletonFactory.getObject();
              //若是获取到了则将singletonObject放入到earlySingletonObjects,也就是将三级缓存提高到二级缓存中
              this.earlySingletonObjects.put(beanName, singletonObject);
              this.singletonFactories.remove(beanName);
          }
        }
    }
  }
  return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

补充一些方法和参数

  • isSingletonCurrentlyInCreation():判断当前单例bean是否正在建立中,也就是没有初始化完成(好比A的构造器依赖了B对象因此得先去建立B对象, 或则在A的populateBean过程当中依赖了B对象,得先去建立B对象,这时的A就是处于建立中的状态。)
  • allowEarlyReference :是否容许从singletonFactories中经过getObject拿到对象。

分析getSingleton()的整个过程,Spring首先从一级缓存singletonObjects中获取。若是获取不到,而且对象正在建立中,就再从二级缓存earlySingletonObjects中获取。若是仍是获取不到且容许singletonFactories经过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,若是获取到了则从三级缓存移动到了二级缓存。从上面三级缓存的分析,咱们能够知道,Spring解决循环依赖的诀窍就在于singletonFactories这个三级cache。这个cache的类型是ObjectFactory,定义以下:

public interface ObjectFactory<T> {
    T getObject() throws BeansException;
}

在bean建立过程当中,有两处比较重要的匿名内部类实现了该接口。一处是Spring利用其建立bean的时候,另外一处就是:

addSingletonFactory(beanName, new ObjectFactory<Object>() {
   @Override   public Object getObject() throws BeansException {
      return getEarlyBeanReference(beanName, mbd, bean);
   }});

此处就是解决循环依赖的关键,这段代码发生在createBeanInstance以后,也就是说单例对象此时已经被建立出来的。这个对象已经被生产出来了,虽然还不完美(尚未进行初始化的第二步和第三步),可是已经能被人认出来了(根据对象引用能定位到堆中的对象),因此Spring此时将这个对象提早曝光出来让你们认识,让你们使用。

好比“A对象setter依赖B对象,B对象setter依赖A对象”,A首先完成了初始化的第一步,而且将本身提早曝光到singletonFactories中,此时进行初始化的第二步,发现本身依赖对象B,此时就尝试去get(B),发现B尚未被create,因此走create流程,B在初始化第一步的时候发现本身依赖了对象A,因而尝试get(A),尝试一级缓存singletonObjects(确定没有,由于A还没初始化彻底),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,因为A经过ObjectFactory将本身提早曝光了,因此B可以经过ObjectFactory.getObject拿到A对象(半成品),B拿到A对象后顺利完成了初始化阶段一、二、三,彻底初始化以后将本身放入到一级缓存singletonObjects中。此时返回A中,A此时能拿到B的对象顺利完成本身的初始化阶段二、三,最终A也完成了初始化,进去了一级缓存singletonObjects中,并且更加幸运的是,因为B拿到了A的对象引用,因此B如今hold住的A对象完成了初始化。

3.3.1 Spring为什么不能解决构造器的循环依赖?

构造器注入形成的循环依赖: 也就是beanB需要在beanA的构造函数中完成初始化,beanA也需要在beanB的构造函数中完成初始化,这种情况的结果就是两个bean都不能完成初始化,循环依赖难以解决。Spring解决循环依赖主要是依赖三级缓存,但是的在调用构造方法之前还未将其放入三级缓存之中,因此后续的依赖调用构造方法的时候并不能从三级缓存中获取到依赖的Bean,因此不能解决。

3.3.2 Spring为什么不能解决prototype作用域循环依赖?

这种循环依赖同样无法解决,因为spring不会缓存‘prototype’作用域的bean,而spring中循环依赖的解决正是通过缓存来实现的。

3.3.3 Spring为什么不能解决多例的循环依赖?

多实例Bean是每次调用一次getBean都会执行一次构造方法并且给属性赋值,根本没有三级缓存,因此不能解决循环依赖。

3.3.4 其它循环依赖如何解决?

  • 生成代理对象产生的循环依赖

这类循环依赖问题解决方法很多,主要有:

  1. 使用@Lazy注解,延迟加载
  2. 使用@DependsOn注解,指定加载先后关系
  3. 修改文件名称,改变循环依赖类的加载顺序
  • 使用@DependsOn产生的循环依赖

这类循环依赖问题要找到@DependsOn注解循环依赖的地方,迫使它不循环依赖就可以解决问题。

  • 多例循环依赖

这类循环依赖问题可以通过把bean改成单例的解决。

  • 构造器循环依赖

这类循环依赖问题可以通过使用@Lazy注解解决。

博文参考

Spring进阶- Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等) | Java 全栈知识体系

Spring IOC源码分析-Bean的生命周期 - 掘金

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring 生命周期Bean 生命周期是密切相关的。在 Spring 容器中,每个 Bean 都有一个完整的生命周期,即从实例化、依赖注入,到销毁的过程,Spring 容器为我们管理了这些过程。Bean 生命周期包括 Bean 的创建、初始化、使用和销毁。具体来说,Spring 生命周期包括以下阶段: 1.实例化 Bean:容器根据配置文件或注解等方式创建 Bean 的实例。 2.设置 Bean 的属性值:容器会将 Bean 的属性值注入到 Bean 中,这是 Bean 生命周期的第二个阶段。Spring 提供了两种常用方式来实现 Bean 的属性注入:构造函数注入和 Setter 方法注入。 3.调用 Bean 的初始化方法:在 Bean 的所有属性被设置之后,Spring 容器会调用 Bean 的初始化方法,这个方法可以是自定义的方法,也可以是 Spring 提供的初始化方法。 4.使用 Bean:在 Bean 初始化完成之后,Spring 容器会将 Bean 注入到需要使用它的地方,比如其他 Bean 或者 Controller 等。 5.销毁 Bean:当 Bean 不再需要时,Spring 容器会调用 Bean 的销毁方法,这个方法可以是自定义的方法,也可以是 Spring 提供的销毁方法。 Bean 生命周期Spring 生命周期的一部分,它描述了一个 Bean 在 Spring 容器中的生命周期Bean 生命周期包括以下阶段: 1.实例化 Bean:容器根据配置文件或注解等方式创建 Bean 的实例。 2.设置 Bean 的属性值:容器会将 Bean 的属性值注入到 Bean 中,这是 Bean 生命周期的第二个阶段。Spring 提供了两种常用方式来实现 Bean 的属性注入:构造函数注入和 Setter 方法注入。 3.调用 Bean 的初始化方法:在 Bean 的所有属性被设置之后,Spring 容器会调用 Bean 的初始化方法,这个方法可以是自定义的方法,也可以是 Spring 提供的初始化方法。 4.使用 Bean:在 Bean 初始化完成之后,Spring 容器会将 Bean 注入到需要使用它的地方,比如其他 Bean 或者 Controller 等。 5.销毁 Bean:当 Bean 不再需要时,Spring 容器会调用 Bean 的销毁方法,这个方法可以是自定义的方法,也可以是 Spring 提供的销毁方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庄小焱

我将坚持分享更多知识

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值