IOC学习总结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

曾经有很长一段时间我对IOC的了解都是很表面的。只知道IOC是控制反转,反转就是将我们创建对象的权力交由Spring进行管理,创建的对象被称为bean。Spring通过容器启动实现IOC。容器启动时,会读取配置文件并将其转化为bean定义信息,最后委托BeanFactory通过bean定义信息完成bean的创建。bean与bean之间是可以依赖注入的(ps 特殊循环依赖除外)。只知道这些理论但从来没有看过源码到底是如何实现的。
突然有一天心血来潮,把容器启动这块重新学习了一遍。基于源码知道了spring是如何实现的这些理论。特此对这阶段的学习做一个总结。

一、容器的使用

//创建容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"org/springframework/context/annotation/scopedProxyDefaultTests.xml");
//获取bean
ScopedProxyTestBean bean = (ScopedProxyTestBean) context.getBean("scopedProxyTestBean");

从使用层面看容器创建后就可以从容器中获取bean了。为什么能获取到bean呢?这需要了解容器启动过程

二、容器启动的主要步骤

容器的启动过程是由AbstractApplicationContext类的refresh方法实现的,ClassPathXmlApplicationContext的构造方法中就会调用该方法完成容器启动。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//刷新准备
			prepareRefresh();

			// 创建bean工厂并加载bean定义信息
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 配置bean工厂
			prepareBeanFactory(beanFactory);

			try {
				//子类实现 这里啥也没干
				postProcessBeanFactory(beanFactory);

				//优先创建一种可以处理bean定义信息的bean,并执行其处理bean定义信息方法
				invokeBeanFactoryPostProcessors(beanFactory);

				//优先创建一种可以处理bean的bean,将其注册到bean工厂中等待后续使用
				registerBeanPostProcessors(beanFactory);

				// 不明觉厉
				initMessageSource();

				// 构建事件监听器容器
				initApplicationEventMulticaster();

				// 创建特殊bean 由子类实现
				// 子类ServletWebServerApplicationContext就是通过实现该接口完成的内置tomcat启动
				onRefresh();

				// 注册消息到消息容器
				registerListeners();

				// 初始化单例懒加载bean
				finishBeanFactoryInitialization(beanFactory);

				// 收尾工作
				finishRefresh();
			}

			catch (BeansException ex) {
				...
			}

			finally {
			    ...
			}
		}
	}

启动的主要步骤有

  • 将BeanDefinition注册到BeanFactory,为后续创建bean做准备
  • 优先创建一种可以修改BeanDefinition的bean,并执行其修改BeanDefinition的方法
  • 优先创建一种可以处理bean的bean,将其注册到BeanFactory以备后用
  • 提前创建单例懒加载bean,上边两步会对其产生影响

ps:很多步骤没有提及是因为暂时的能力还无法将其总结出来


2.1、将BeanDefinition注册到BeanFactory

将BeanDefinition注册到BeanFactory,首先需要创建BeanFactory其次是构建BeanDefinition信息,最终完成注册。源码主要步骤如下

  • 容器完成BeanFactory和XmlBeanDefinitionReader的创建
  • XmlBeanDefinitionReader将资源路径转化为Document对象并构建DefaultBeanDefinitionDocumentReader
  • DefaultBeanDefinitionDocumentReader将Document对象转化为BeanDefinition完成最终的注册

接下来基于源码跟下这个流程

2.1.1、容器完成BeanFactory和XmlBeanDefinitionReader的创建

从AbstractApplicationContext类开始,跟obtainFreshBeanFactory方法。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//该方法由子类AbstractRefreshableApplicationContext实现
	refreshBeanFactory();
	return getBeanFactory();
}

跟AbstractRefreshableApplicationContext的refreshBeanFactory方法

protected final void refreshBeanFactory() throws BeansException {
		//这个分支略过
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//主要看这个方法
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			//加载BeanDefinition的入口
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
		...
		}
	}

//BeanFactory被创建
protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

到这里BeanFactory已经被创建了,继续跟loadBeanDefinitions方法。该方法由子类AbstractXmlApplicationContext实现

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 创建XmlBeanDefinitionReader并将beanFactory交给他
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		//设置资源处理器 容器本身就是资源处理器
		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);
		//这里可以看到后续加载BeanDefinition统一交给XmlBeanDefinitionReader进行处理了
		loadBeanDefinitions(beanDefinitionReader);
	}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
	Resource[] configResources = getConfigResources();
	if (configResources != null) {
		reader.loadBeanDefinitions(configResources);
	}
	String[] configLocations = getConfigLocations();
	if (configLocations != null) {
		//这里的configLocations就是容器构造函数中的字符串
		reader.loadBeanDefinitions(configLocations);
	}
}

总结:容器阶段创建了BeanFactory和XmlBeanDefinitionReader。然后将BeanFactory、资源加载器(容器本身)、资源路径统统交给XmlBeanDefinitionReader来继续进行BeanDefinition的加载。

2.1.2、XmlBeanDefinitionReader将资源路径转化为Document对象并构建DefaultBeanDefinitionDocumentReader

这个过程比较复杂,先整理下源码的大致流程

  • XmlBeanDefinitionReader通过父类AbstractBeanDefinitionReader将资源路径转化为Resource(资源对象)
  • XmlBeanDefinitionReader先将Resource转化为InputSource,然后将InputSource转化为Document
  • 创建BeanDefinitionDocumentReader完成后续工作

跟源码看下这个流程

从reader.loadBeanDefinitions方法开始,这里的reader会调用其父类AbstractBeanDefinitionReader的方法。

//入口方法 处理数组资源路径
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
	Assert.notNull(locations, "Location array must not be null");
	int count = 0;
	for (String location : locations) {
		//进入方法2  处理单个资源路径
		count += loadBeanDefinitions(location);
	}
	return count;
}

//方法2 处理单个资源路径
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
	//进入父类核心方法
	return loadBeanDefinitions(location, null);
}

//父类核心方法 将资源路径转化为资源集合
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
	//获取资源加载器 其实就是容器
	ResourceLoader resourceLoader = getResourceLoader();
	。。省略代码
	if (resourceLoader instanceof ResourcePatternResolver) {
		// Resource pattern matching available.
		try {
			//通过资源解析器获取资源
			Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
			//进入方法3 处理多个资源对象
			int count = loadBeanDefinitions(resources);
			。。省略代码
			return count;
		}
		catch (IOException ex) {
			。。省略代码
		}
	}
	//略过这个分支
	else {
		// Can only load single resources by absolute URL.
		Resource resource = resourceLoader.getResource(location);
		int count = loadBeanDefinitions(resource);
		return count;
	}
}

//方法3 处理多个资源对象
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
	Assert.notNull(resources, "Resource array must not be null");
	int count = 0;
	for (Resource resource : resources) {
	    //最后交给子类来实现
		count += loadBeanDefinitions(resource);
	}
	return count;
}

这个过程AbstractBeanDefinitionReader用了大量重载方法。先将资源路径数组拆分成单个资源路径,再将单个资源路径通过资源加载器变成资源数组。最后将资源数组拆分成一个个资源交由子类继续处理。接着跟XmlBeanDefinitionReader的loadBeanDefinitions方法

//入口方法
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
	//将资源对象编码进入方法2
	return loadBeanDefinitions(new EncodedResource(resource));
}

//方法2 将Resource转化为InputSource 
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		。。。省略代码
		try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
			InputSource inputSource = new InputSource(inputStream);
			。。。省略代码
			//进入方法3 继续处理
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		catch (IOException ex) {
			。。。省略代码
		}
		finally {
	     	。。。省略代码
		}
}

//方法3 将InputSource转化为Document 
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
		throws BeanDefinitionStoreException {
	try {
	    //将资源加载成Document对象
		Document doc = doLoadDocument(inputSource, resource);
		//进入方法4 继续处理
		int count = registerBeanDefinitions(doc, resource);
		。。。省略代码
		return count;
	}
		。。。省略代码
}

//方法4 构建BeanDefinitionDocumentReader 准备完成最后的工作
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
	int countBefore = getRegistry().getBeanDefinitionCount();
	//委托给BeanDefinitionDocumentReader类完成后续的注册流程
	documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
	return getRegistry().getBeanDefinitionCount() - countBefore;
}

//将BeanDefinitionDocumentReader用到的对象统一封装到XmlReaderContext中,这里包含其本身,而其本身包含bean工厂
public XmlReaderContext createReaderContext(Resource resource) {
	return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
			this.sourceExtractor, this, getNamespaceHandlerResolver());
}

总结:XmlBeanDefinitionReader将资源路径转化为Document对象,然后将携带BeanFactory的自己和Resource等对象统一打包成XmlReaderContext对象。将二者传递给新构建的BeanDefinitionDocumentReader对象用于完成最终的加载BeanDefinition任务。

2.1.3、DefaultBeanDefinitionDocumentReader将Document对象转化为BeanDefinition完成最终的注册

跟进BeanDefinitionDocumentReader的registerBeanDefinitions方法

//入口方法
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
	this.readerContext = readerContext;
	//进入方法1
	doRegisterBeanDefinitions(doc.getDocumentElement());
}
//方法1 执行BeanDefinition注册
protected void doRegisterBeanDefinitions(Element root) {
	BeanDefinitionParserDelegate parent = this.delegate;
	//创建BeanDefinitionParserDelegate对象 用于解析Element为BeanDefinition
	this.delegate = createDelegate(getReaderContext(), root, parent);
	//略过这个步骤
	if (this.delegate.isDefaultNamespace(root)) {
		...}
	//前置处理 略
	preProcessXml(root);
	//进入方法2
	parseBeanDefinitions(root, this.delegate);
	//后置处理 略
	postProcessXml(root);
	this.delegate = parent;
}
//方法2 执行BeanDefinition注册 针对默认标签和自定义标签的两种解析方式 本次重点看默认解析方式parseDefaultElement
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
	if (delegate.isDefaultNamespace(root)) {
		NodeList nl = root.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
				if (delegate.isDefaultNamespace(ele)) {
					//默认解析
					//进入方法3
					parseDefaultElement(ele, delegate);
				}
				else {
					//自定义解析
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
	else {
		//自定义解析
		delegate.parseCustomElement(root);
	}
}
//方法3 默认标签解析 重点看bean标签解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
		importBeanDefinitionResource(ele);
	}
	else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
		processAliasRegistration(ele);
	}
	else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
		//进入方法4 bean标签解析
		processBeanDefinition(ele, delegate);
	}
	else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
		// recurse
		doRegisterBeanDefinitions(ele);
	}
}
//方法4 最终的解析注册
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	//使用delegate将Element转化为BeanDefinition
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			//执行注册,第一个参数携带为BeanDefinition,第二个参数是上下文中携带的BeanFactory
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// Send registration event.
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

总结:DefaultBeanDefinitionDocumentReader委托delegate【BeanDefinitionParserDelegate】将Element转化为携带BeanDefinitionr的BeanDefinitionHolder,最后在上下文中拿到BeanFactory完成注册

2.2、 优先创建一种可以修改BeanDefinition的bean,并执行其修改BeanDefinition的方法

BeanFactoryPostProcessor类型的bean可以在bean创建之前对BeanDefinition做修改。为什么要优先创建这种bean呢?举个例子PropertyPlaceholderConfigurer是BeanFactoryPostProcessor的子类,他可以将BeanDefinition中${bean.message}替换成真实的值

<bean id="message" class="distConfig.HelloMessage">
	<property name="mes">
    	<value>${bean.message}</value>
    </property>
</bean>

<bean id="mesHandler" class="org.Springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location">
    	<list>
        	<value>config/bean.properties</value>
        </list>
    </property>
</bean>

因为其影响到了后续bean的创建,所以必须在创建其他bean之前优先创建这种bean,并执行其修改BeanDefinition的方法。

为了更好的理解源码,这里还需要先扫个盲。
BeanFactoryPostProcessor通过调用postProcessBeanFactory方法完成BeanDefinition的修改。其中BeanDefinitionRegistryPostProcessor是一种特殊的BeanFactoryPostProcessor,其不但具有前者的方法,其本身还有一个postProcessBeanDefinitionRegistry方法用于注册新的BeanDefinition。为了保证后添加的BeanDefinition也能被BeanFactoryPostProcessor处理,所以postProcessBeanDefinitionRegistry方法需要优先执行。

继续跟源码,从AbstractApplicationContext类开始,跟invokeBeanFactoryPostProcessors方法。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//重点跟这里,一个乱的登峰造极的方法
	//getBeanFactoryPostProcessors方法会拿到容器中所有的BeanFactoryPostProcessor
	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()));
	}
}

下边要跟的方法非常长,方法主要就是按顺序执行postProcessBeanDefinitionRegistry和postProcessBeanFactory方法。先梳理下整体顺序方便后续跟源码

postProcessBeanDefinitionRegistry执行顺序

  • 容器中的BeanDefinitionRegistryPostProcessor
  • 工厂中实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor【内部还有排序】
  • 工厂中实现了Ordered的BeanDefinitionRegistryPostProcessor【内部还有排序】
  • 工厂中剩余的BeanDefinitionRegistryPostProcessor【内部还有排序】

postProcessBeanFactory执行顺序

  • 所有的BeanDefinitionRegistryPostProcessor【顺序和执行postProcessBeanDefinitionRegistry一致】
  • 容器中的BeanFactoryPostProcessor
  • 工厂中实现了PriorityOrdered的BeanFactoryPostProcessor【内部还有排序】
  • 工厂中实现了Ordered的BeanFactoryPostProcessor【内部还有排序】
  • 工厂剩余的BeanFactoryPostProcessor【内部还有排序】

跟PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors

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

	//=====================================执行postProcessBeanDefinitionRegistry=======================================
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				//1 容器中的BeanDefinitionRegistryPostProcessor优先执行
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				regularPostProcessors.add(postProcessor);
			}
		}

		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		//获取工厂中所有BeanDefinitionRegistryPostProcessor的BeanName
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		//排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);
		//2 工厂中实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		//为什么要重新获取BeanDefinitionRegistryPostProcessor的BeanName?
		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);
		//3 工厂中实现了Ordered的BeanDefinitionRegistryPostProcessor
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		//为什么要使用死循环?
		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);
			//4 工厂中剩余的BeanDefinitionRegistryPostProcessor
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}

//=====================================执行postProcessBeanFactory=======================================


		//1 所有的BeanDefinitionRegistryPostProcessor
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		//2 容器中的BeanFactoryPostProcessor
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}
	//这个分支略
	else {
		....
	}

	//获取工厂中所有的BeanFactoryPostProcessor
	String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	//用于保存priorityOrdered类型的BeanFactoryPostProcessor
	List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	//用于保存Ordered类型的BeanFactoryPostProcessor的beanName
	List<String> orderedPostProcessorNames = new ArrayList<>();
	//用于保存剩余的BeanFactoryPostProcessor的beanName
	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);
		}
	}

	//3 工厂中实现了PriorityOrdered的BeanFactoryPostProcessor
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    //4 工厂中实现了Ordered的BeanFactoryPostProcessor
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    //5 工厂剩余的BeanFactoryPostProcessor
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	//略 目前还没看懂
	beanFactory.clearMetadataCache();
}

源码中主要步骤都做了标记,整体就是按顺序执行postProcessBeanDefinitionRegistry和postProcessBeanFactory方法。发现了两个问题,在这里做个说明

  • 为什么每次执行完postProcessBeanDefinitionRegistry,下一次还要去工厂中重新拿一次BeanDefinitionRegistryPostProcessor?
  • 最有处理剩余的BeanDefinitionRegistryPostProcessor时为什么要使用死循环

这都是因为postProcessBeanDefinitionRegistry会新增BeanDefinition,而新增的BeanDefinition很可能是一个BeanDefinitionRegistryPostProcessor

2.3、 优先创建一种可以处理bean的bean,将其注册到BeanFactory以备后用

BeanPostProcessor是一种用于对bean进行后处理的bean。其一般对bean在实例化前后、初始化前后进行处理。其中AOP技术就是通过BeanPostProcessor来实现的。容器启动时会将这种bean提前创建并注册到BeanFactory以备后用。

继续跟源码,从AbstractApplicationContext类开始,跟registerBeanPostProcessors方法。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//重点跟这个方法
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

这个方法主要目的是将BeanPostProcessor按照顺序构建并注册到BeanFactory。主要流程如下

  • 工厂中实现了PriorityOrdered的BeanPostProcessor先创建、然后排序、注册。
  • 工厂中实现了Ordered的BeanPostProcessor先创建、然后排序、注册
  • 工厂中剩余的BeanPostProcessor创建、排序、注册
  • 将MergedBeanDefinitionPostProcessor类型的处理器排序、注册
    继续跟这个方法
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		//用于保存实现了PriorityOrdered的BeanPostProcessor
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//用于保存实现了MergedBeanDefinitionPostProcessor的BeanPostProcessor
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		//用于保存实现了Ordered的BeanPostProcessor的beanName
		List<String> orderedPostProcessorNames = new ArrayList<>();
		//用于剩余的BeanPostProcessor的beanName
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();

	
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				//1.1 工厂中实现了PriorityOrdered的BeanPostProcessor优先创建
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				//4.1 将MergedBeanDefinitionPostProcessor类型的缓存到internalPostProcessors集合中
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		//1.2 工厂中实现了PriorityOrdered的BeanPostProcessor排序、最后缓存
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		//2 工厂中实现了Ordered的BeanPostProcessor先创建、然后排序、最后缓存
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			//4.2 将MergedBeanDefinitionPostProcessor类型的缓存到internalPostProcessors集合中
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		//3 工厂中剩余的BeanPostProcessor创建、排序、缓存
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			//4.3 将MergedBeanDefinitionPostProcessor类型的缓存到internalPostProcessors集合中
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		//4.4 将MergedBeanDefinitionPostProcessor类型的处理器从缓存中拿出来统一放到最后
		sortPostProcessors(internalPostProcessors, beanFactory);
		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).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

源码中可能会产生一个问题,MergedBeanDefinitionPostProcessor类型的bean被注册了两次会不会导致重复注册?答案是不会的。下面跟下注册方法registerBeanPostProcessors

private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

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

最终调用了beanFactory的addBeanPostProcessor方法。该方法由AbstractBeanFactory实现,继续跟进

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
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
		// Add to end of list
		this.beanPostProcessors.add(beanPostProcessor);
}

注册的方式是先删除后添加,也就是之前注册的MergedBeanDefinitionPostProcessor会被删除。然后统一注册到集合的末尾。

2.4、 提前创建单例懒加载bean

这个步骤是容器委托BeanFactory来完成的。主要步骤如下

  • 委托BeanFactory完成单例懒加载bean的创建
  • BeanFactory找到所有单例懒加载的beanName,通过getBean完成bean的创建

继续跟源码,从AbstractApplicationContext类开始,跟finishBeanFactoryInitialization方法。

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

		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		beanFactory.setTempClassLoader(null);

		beanFactory.freezeConfiguration();

		//重点跟这里 委托beanFactory完成初始化单例懒加载bean
		beanFactory.preInstantiateSingletons();
	}

preInstantiateSingletons方法由DefaultListableBeanFactory实现,继续跟进

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		//拿到所有beanname
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		//便利
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//判断是不是单例懒加载的bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//如果是FactoryBean的判断,这里不重点介绍了,最后也调用了getBean
				if (isFactoryBean(beanName)) {
				    ...}
				else {
					//执行getbean完成创建
					getBean(beanName);
				}
			}
		}
		....}

getBean是BeanFactory最主要的方法,Demo中就是通过该方法拿到的bean实例。该方法的核心方法链如下
getBean-》doGetBean-》createBean-》doCreateBean。下面依次看下这个方法链中各个方法的作用

2.4.1、 getBean方法执行过程

getBean方法由AbstractBeanFactory类实现,继续跟进

public Object getBean(String name) throws BeansException {
	//核心逻辑在doGetBean中
	return doGetBean(name, null, null, false);
}

继续跟进

2.4.2、 doGetBean方法执行过程

doGetBean方法依然由AbstractBeanFactory类实现,这个方法非常长这里先列出其主要流程

  • 当前bean在缓存中存在,直接返回
  • 如果当前BeanFactory有父亲并且自己没有该bean的BeanDefinition。调用父亲的getBean
  • 根据bean的scope类型(单例、多例、其他)进行bean的创建。最终都会执行createBean方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		//1 当前bean在缓存中存在,直接返回
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
		
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			//2 如果当前BeanFactory有父亲并且自己没有该bean的BeanDefinition。调用父亲的getBean
			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) {
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				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);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				//3.1单例bean的创建
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//3.2多例bean的创建
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//3.2 其他类型bean的创建
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

2.4.2、 createBean方法执行过程

继续跟进createBean,该方法由AbstractAutowireCapableBeanFactory实现。这里出现了对BeanPostProcessor的首次使用,真正的核心逻辑需要继续跟进doCreateBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		...
		RootBeanDefinition mbdToUse = mbd;

		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		...try {
			//对BeanPostProcessor的首次使用【postProcessBeforeInitialization】
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		...
		try {
			//创建bean的核心方法
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		...
	}


//对BeanPostProcessor的首次使用
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//依次执行BeanPostProcessor的postProcessBeforeInstantiation方法
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						//依次执行BeanPostProcessor的postProcessAfterInitialization方法
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

2.4.2、 doCreateBean方法执行过程

继续跟进doCreateBean,该方法也由AbstractAutowireCapableBeanFactory实现。主要步骤如下

  • 创建bean实例
  • 依赖注入
  • bean的初始化
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		//创建bean实例
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//BeanPostProcessor的第二次使用【postProcessMergedBeanDefinition】
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		//解决循环依赖 这里不重点介绍了
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//完成依赖注入
			//这里包含BeanPostProcessor的第三、四次使用【postProcessAfterInstantiation、(postProcessProperties、postProcessPropertyValues)】
			populateBean(beanName, mbd, instanceWrapper);
			//完成bean的初始化
			//这里包含BeanPostProcessor的第五、六次使用[postProcessBeforeInitialization、postProcessAfterInitialization]
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

到这里bean的创建、依赖注入、初始化就完成了。


总结

容器启动(IOC)的过程就是在创建各种bean。首先加载bean定义信息为创建bean做准备,然后创建BeanFactoryPostProcessor类型的bean,该bean可以新增和修改bean定义信息。在然后创建BeanPostProcessor类型的bean,该bean可以对普通bean做处理。最后创建普通的单例懒加载bean,期间6次调用BeanPostProcessor处理器。
整体来说粒度很粗、主要是想突出IOC的主流程,已目前的总结水平,加入太多细节会让流程开起来非常复杂凌乱。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值