Spring——spring IOC源码分析

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


摘要

控制反转(Inversion of Control,缩写为IoC),是面向对象设计中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI。控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。Spring IoC 的实现原理:Spring 中的 IoC 的实现原理就是工厂模式加反射机制。基础概念中实例化:在堆中开启一块空间,属性都是默认值。初始化:给属性完成赋值操作(填充属性,赋值) (调用具体的初始化方法)。

Spring——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的子接口。

Spring——spring IOC源码分析_spring_02

Spring——spring IOC源码分析_加载_03

Spring——spring IOC源码分析_spring_04

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 容器实现类

Spring——spring IOC源码分析_实例化_05

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

1.3 spring IOC核心组件

Spring——spring IOC源码分析_spring_06

1.3.1 Resource 体系

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

Spring——spring IOC源码分析_实例化_07

1.3.2 BeanDefinition 体系

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

Spring——spring IOC源码分析_spring_08

1.3.3 BeanDefinitionReader 体系

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

Spring——spring IOC源码分析_实例化_09

1.3.4 BeanFactory 体系

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

Spring——spring IOC源码分析_实例化_10

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的生命周期 四个阶段

Spring——spring IOC源码分析_实例化_11

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

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

Spring——spring IOC源码分析_加载_12

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

Spring——spring IOC源码分析_加载_13

上面实例化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());

   }
}

Spring——spring IOC源码分析_实例化_14

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

Spring——spring IOC源码分析_实例化_15

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) {
}

Spring——spring IOC源码分析_spring_16

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相关

Spring——spring IOC源码分析_实例化_17

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);
    }
}

Spring——spring IOC源码分析_实例化_18

 注意两个比较容易踩的坑

  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中的Bean的生命周期

Spring——spring IOC源码分析_实例化_19

Spring——spring IOC源码分析_加载_20

Spring——spring IOC源码分析_spring_21

博文参考

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring