GVKun编程网logo

Spring 源码解读第七弹!bean 标签的解析(spring中bean标签的作用)

31

最近很多小伙伴都在问Spring源码解读第七弹!bean标签的解析和spring中bean标签的作用这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展4.3spring-嵌入式bea

最近很多小伙伴都在问Spring 源码解读第七弹!bean 标签的解析spring中bean标签的作用这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展4.3 spring-嵌入式beans标签的解析、Spring bean 创建过程源码解析、spring beans源码解读之--bean definiton解析器、Spring IoC 源码解析之 getBean等相关知识,下面开始了哦!

本文目录一览:

Spring 源码解读第七弹!bean 标签的解析(spring中bean标签的作用)

Spring 源码解读第七弹!bean 标签的解析(spring中bean标签的作用)

Spring 源码解读继续。

本文是 Spring 系列第八篇,如果小伙伴们还没阅读过本系列前面的文章,建议先看看,这有助于更好的理解本文。

  1. Spring 源码解读计划
  2. Spring 源码第一篇开整!配置文件是怎么加载的?
  3. Spring 源码第二弹!XML 文件解析流程
  4. Spring 源码第三弹!EntityResolver 是个什么鬼?
  5. Spring 源码第四弹!深入理解 BeanDefinition
  6. 手把手教你搭建 Spring 源码分析环境
  7. Spring 源码第六弹!松哥和大家聊聊容器的始祖 DefaultListableBeanFactory

1.前文回顾

不知道小伙伴们是否还记得,在前面我们讲 Spring 文档加载的时候,涉及到如下一段源码:

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
		throws BeanDefinitionStoreException {
	try {
		Document doc = doLoadDocument(inputSource, resource);
		int count = registerBeanDefinitions(doc, resource);
		if (logger.isDebugEnabled()) {
			logger.debug("Loaded " + count + " bean definitions from " + resource);
		}
		return count;
	}
	catch (BeanDefinitionStoreException ex) {
		throw ex;
	}
	catch (SAXParseException ex) {
		throw new XmlBeanDefinitionStoreException(resource.getDescription(),
				"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
	}
	catch (SAXException ex) {
		throw new XmlBeanDefinitionStoreException(resource.getDescription(),
				"XML document from " + resource + " is invalid", ex);
	}
	catch (ParserConfigurationException ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"Parser configuration exception parsing XML from " + resource, ex);
	}
	catch (IOException ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"IOException parsing XML document from " + resource, ex);
	}
	catch (Throwable ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"Unexpected exception parsing XML document from " + resource, ex);
	}
}

这段代码就两个核心方法:

  1. 首先调用 doLoadDocument 方法获取 Spring 的 XML 配置文件加载出来的 Document 文档对象,这个方法的执行流程我们在前面已经介绍过了,这里就不再赘述。
  2. 接下来就是调用 registerBeanDefinitions 方法,讲加载出来的文档对象进行解析,定义出相应的 BeanDefinition 对象出来。

BeanDefinition 是什么,有什么作用,松哥在之前的 Spring 源码第四弹!深入理解 BeanDefinition 一文中已经做过介绍,这里就不再赘述。

本文我们就来看看 Document 对象是如何一步一步加载成 BeanDefinition 的。

2.parseDefaultElement

我们就从 registerBeanDefinitions 方法开始看起:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
	int countBefore = getRegistry().getBeanDefinitionCount();
	documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
	return getRegistry().getBeanDefinitionCount() - countBefore;
}

这里通过调用 createBeanDefinitionDocumentReader 方法获取到一个 BeanDefinitionDocumentReader 的实例,具体的对象则是 DefaultBeanDefinitionDocumentReader,也就是说接下来调用 DefaultBeanDefinitionDocumentReader#registerBeanDefinitions 进行解析。继续来看该方法的定义:

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
	this.readerContext = readerContext;
	doRegisterBeanDefinitions(doc.getDocumentElement());
}

这里又调用到了 doRegisterBeanDefinitions 方法继续完成注册:

protected void doRegisterBeanDefinitions(Element root) {
	// Any nested <beans> elements will cause recursion in this method. In
	// order to propagate and preserve <beans> default-* attributes correctly,
	// keep track of the current (parent) delegate, which may be null. Create
	// the new (child) delegate with a reference to the parent for fallback purposes,
	// then ultimately reset this.delegate back to its original (parent) reference.
	// this behavior emulates a stack of delegates without actually necessitating one.
	BeanDefinitionParserDelegate parent = this.delegate;
	this.delegate = createDelegate(getReaderContext(), root, parent);
	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.
			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;
}

这个方法流程比较简单,首先检查了一下有没有 profile 需要处理(如果有人不清楚 Spring 中的 profile,可以在公众号后台回复 spring5 获取松哥录制的免费的 Spring 入门教程)。处理完 profile 之后,接下来就是解析了,解析有一个前置处理方法 preProcessXml 和后置处理方法 postProcessXml,不过这两个方法默认都是空方法,真正的解析方法是 parseBeanDefinitions:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
	if (delegate.isDefaultNamespace(root)) {
		NodeList nl = root.getChildNodes();
		for (int i = 0; i &lt; nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
				if (delegate.isDefaultNamespace(ele)) {
					parseDefaultElement(ele, delegate);
				}
				else {
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
	else {
		delegate.parseCustomElement(root);
	}
}

在该方法中进行节点的解析,最终会来到 parseDefaultElement 方法中。我们一起来看下该方法:

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)) {
		processBeanDefinition(ele, delegate);
	}
	else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
		// recurse
		doRegisterBeanDefinitions(ele);
	}
}

终于来到期盼已久的 parseDefaultElement 方法中了。

在该方法中,我们可以看到,节点一共被分为了四大类:

  • import
  • alias
  • bean
  • beans

每一个节点都好理解,因为我们在开发中可能多多少少都有用过,需要注意的是,如果是 beans 节点,又会再次调用 doRegisterBeanDefinitions 方法进行递归解析,源码上面还给了一个注释 recurse,意思就是递归。

四种类型的节点解析,我们就从 bean 的解析看起吧,因为 beans 节点是我们最常用的节点,这个搞清楚了,另外三个节点就可以举一反三了。

我们来看 processBeanDefinition 方法:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// Register the final decorated instance.
			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));
	}
}

在这段代码中,首先调用代理类 BeanDefinitionParserDelegate 对元素进行解析,解析的结果会保存在 bdHolder 中,也就是 bean 节点中配置的元素 class、id、name 等属性,在经过这一步的解析之后,都会保存到 bdHolder 中。

如果 bdHolder 不为空,那么接下来对子节点的属性继续解析,同时对 bdHolder 进行注册,最终发出事件,通知这个 bean 节点已经加载完了。

如此看来,整个解析的核心过程应该在 delegate.parseBeanDefinitionElement(ele) 方法中,追踪该方法的执行,我们最终来到这里:

@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
	String id = ele.getAttribute(ID_ATTRIBUTE);
	String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
	List<string> aliases = new ArrayList&lt;&gt;();
	if (StringUtils.hasLength(nameAttr)) {
		String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
		aliases.addAll(Arrays.asList(nameArr));
	}
	String beanName = id;
	if (!StringUtils.hasText(beanName) &amp;&amp; !aliases.isEmpty()) {
		beanName = aliases.remove(0);
		if (logger.isTraceEnabled()) {
			logger.trace("No XML ''id'' specified - using ''" + beanName +
					"'' as bean name and " + aliases + " as aliases");
		}
	}
	if (containingBean == null) {
		checkNameUniqueness(beanName, aliases, ele);
	}
	AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
	if (beanDefinition != null) {
		if (!StringUtils.hasText(beanName)) {
			try {
				if (containingBean != null) {
					beanName = BeanDefinitionReaderUtils.generateBeanName(
							beanDefinition, this.readerContext.getRegistry(), true);
				}
				else {
					beanName = this.readerContext.generateBeanName(beanDefinition);
					// Register an alias for the plain bean class name, if still possible,
					// if the generator returned the class name plus a suffix.
					// This is expected for Spring 1.2/2.0 backwards compatibility.
					String beanClassName = beanDefinition.getBeanClassName();
					if (beanClassName != null &amp;&amp;
							beanName.startsWith(beanClassName) &amp;&amp; beanName.length() &gt; beanClassName.length() &amp;&amp;
							!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
						aliases.add(beanClassName);
					}
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Neither XML ''id'' nor ''name'' specified - " +
							"using generated bean name [" + beanName + "]");
				}
			}
			catch (Exception ex) {
				error(ex.getMessage(), ele);
				return null;
			}
		}
		String[] aliasesArray = StringUtils.toStringArray(aliases);
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}
	return null;
}

这个方法中所作的事情我们可以大致分为 5 个步骤:

  1. 提取出 id 和 name 属性值。
  2. 检查 beanName 是否唯一。
  3. 对节点做进一步的解析,解析出 beanDefinition 对象,真是的类型是 GenericBeanDefinition。
  4. 如果 beanName 属性没有值,则使用默认的规则生成 beanName(默认规则是类名全路径)。
  5. 最终将获取到的信息封装成一个 BeanDefinitionHolder 返回。

在这一层面主要完成了对 id 和 name 的处理,如果用户没有给 bean 定义名称的话,则生成一个默认的名称,至于其他属性的解析,则主要是在 parseBeanDefinitionElement 方法中完成的。

@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
		Element ele, String beanName, @Nullable BeanDefinition containingBean) {
	this.parseState.push(new BeanEntry(beanName));
	String className = null;
	if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
		className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
	}
	String parent = null;
	if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
		parent = ele.getAttribute(PARENT_ATTRIBUTE);
	}
	try {
		AbstractBeanDefinition bd = createBeanDefinition(className, parent);
		parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
		bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
		parseMetaElements(ele, bd);
		parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
		parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
		parseConstructorArgElements(ele, bd);
		parsePropertyElements(ele, bd);
		parseQualifierElements(ele, bd);
		bd.setResource(this.readerContext.getResource());
		bd.setSource(extractSource(ele));
		return bd;
	}
	catch (ClassNotFoundException ex) {
		error("Bean class [" + className + "] not found", ele, ex);
	}
	catch (NoClassDefFoundError err) {
		error("Class that bean class [" + className + "] depends on not found", ele, err);
	}
	catch (Throwable ex) {
		error("Unexpected failure during bean definition parsing", ele, ex);
	}
	finally {
		this.parseState.pop();
	}
	return null;
}
  1. 首先解析出 className 属性。
  2. 解析出 parent 属性。
  3. 调用 createBeanDefinition 方法创建出用于保存对象的 BeanDefinition,既 GenericBeanDefinition。
  4. parseBeanDefinitionAttributes 用来解析出各种各样的节点属性。
  5. parseMetaElements 用来解析 Meta 数据。
  6. parseLookupOverrideSubElements 解析 lookup-method 属性。
  7. parseReplacedMethodSubElements 解析 replace-method 属性。
  8. parseConstructorArgElements 解析构造函数参数。
  9. parsePropertyElements 解析 property 子元素。
  10. parseQualifierElements 解析 qualifier 子元素。
  11. 最终返回 bd。

可以看到,bean 节点中所有的属性都解析了,有的是我们日常常见的属性,有的是我们不常见的甚至从来都没见到过的,无论哪种情况,现在全部都解析了。解析完成后,将获得的 GenericBeanDefinition 返回。

3. 常规属性解析

这里有一些属性的解析可能比较冷门,这个我一会说,还有一些比较常规,例如 parseBeanDefinitionAttributes 方法用来解析各种各样的节点属性,这些节点属性可能大家都比较熟悉,我们一起来看下:

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
		@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
	if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
		error("Old 1.x ''singleton'' attribute in use - upgrade to ''scope'' declaration", ele);
	}
	else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
		bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
	}
	else if (containingBean != null) {
		// Take default from containing bean in case of an inner bean definition.
		bd.setScope(containingBean.getScope());
	}
	if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
		bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
	}
	String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
	if (isDefaultValue(lazyInit)) {
		lazyInit = this.defaults.getLazyInit();
	}
	bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
	String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
	bd.setAutowireMode(getAutowireMode(autowire));
	if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
		String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
		bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
	}
	String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
	if (isDefaultValue(autowireCandidate)) {
		String candidatePattern = this.defaults.getAutowireCandidates();
		if (candidatePattern != null) {
			String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
			bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
		}
	}
	else {
		bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
	}
	if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
		bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
	}
	if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
		String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
		bd.setInitMethodName(initMethodName);
	}
	else if (this.defaults.getInitMethod() != null) {
		bd.setInitMethodName(this.defaults.getInitMethod());
		bd.setEnforceInitMethod(false);
	}
	if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
		String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
		bd.setDestroyMethodName(destroyMethodName);
	}
	else if (this.defaults.getDestroyMethod() != null) {
		bd.setDestroyMethodName(this.defaults.getDestroyMethod());
		bd.setEnforceDestroyMethod(false);
	}
	if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
		bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
	}
	if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
		bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
	}
	return bd;
}

可以看到,这里解析的节点属性,从上往下,依次是:

  1. 解析 singleton 属性(该属性已废弃,使用 scope 替代)。
  2. 解析 scope 属性,如果未指定 scope 属性,但是存在 containingBean,则使用 containingBean 的 scope 属性值。
  3. 解析 abstract 属性。
  4. 解析 lazy-init 属性。
  5. 解析 autowire 属性。
  6. 解析 depends-on 属性。
  7. 解析 autowire-candidate 属性。
  8. 解析 primary 属性。
  9. 解析 init-method 属性。
  10. 解析 destroy-method 属性。
  11. 解析 factory-method 属性。
  12. 解析 factory-bean 属性。

这些属性作用大家都比较熟悉。因为日常用的多一些。

前面提到的解析中,lookup-method、replace-method、以及 qualifier 等属性可能大家日常都很少用到,甚至没有听说过,如果用都没用过,那源码肯定不好理解,所以接下来松哥会录制一个视频,来和大家讲一讲这些冷门属性的使用,然后我们再继续深入解析这里的 parseMetaElements、parseLookupOverrideSubElements 等方法。

4. Bean 的生成

有了 BeanDefinitionHolder 之后,接下来 Bean 的生成就很容易了。

大家回顾如下两篇文章来理解有了 BeanDefinition 之后,如何转化为具体的 Bean:

  • Spring 源码第四弹!深入理解 BeanDefinition
  • Spring 源码第六弹!松哥和大家聊聊容器的始祖 DefaultListableBeanFactory

好啦,今天的文章就先说这么多~</string></beans></beans>

4.3 spring-嵌入式beans标签的解析

4.3 spring-嵌入式beans标签的解析

  对于嵌入式的beans标签,想信大家很少使用过,或者接触过,起码,我本人就没用过. 它非常类似于Import标签所提供的功能;

使用如下:

<?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-2.5.xsd">
    <beans></beans>
</beans>

  对这个beans没什么太多可讲,解析代码如下:

 1 protected void doRegisterBeanDefinitions(Element root) {
 2         String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
 3         // 处理profile属性
 4         /*
 5          * this is header...
 6          * 
 7          * <beans profile = ''dev"></beans>
 8          * 
 9          * <beans profile = ''production"></beans>
10          * 
11          * web.xml
12          * 
13          * <context-param>
14          * 
15          * <param-name>Spring.profiles.active</param-name>
16          * 
17          * <param-value>dev</param-value>
18          * 
19          * </context-param>
20          */
21         if (StringUtils.hasText(profileSpec)) {
22             Assert.state(this.environment != null,
23                     "Environment must be set for evaluating profiles");
24             String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec,
25                     BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
26             if (!this.environment.acceptsProfiles(specifiedProfiles)) {
27                 return;
28             }
29         }
30 
31         // Any nested <beans> elements will cause recursion in this method. In
32         // order to propagate and preserve <beans> default-* attributes correctly,
33         // keep track of the current (parent) delegate, which may be null. Create
34         // the new (child) delegate with a reference to the parent for fallback purposes,
35         // then ultimately reset this.delegate back to its original (parent) reference.
36         // this behavior emulates a stack of delegates without actually necessitating one.
37         // 专门处理解析
38         BeanDefinitionParserDelegate parent = this.delegate;
39         this.delegate = createDelegate(this.readerContext, root, parent);
40         // 解析前留给子类实现
41         preProcessXml(root);
42 
43         parseBeanDefinitions(root, this.delegate);
44         // 解析后留给子类实现
45         postProcessXml(root);
46 
47         this.delegate = parent;
48     }

 

 

Spring bean 创建过程源码解析

Spring bean 创建过程源码解析

相关文章

Spring 中 bean 注册的源码解析

前言

在上一篇文件 Spring 中 bean 注册的源码解析 中分析了 Spring 中 bean 的注册过程,就是把配置文件中配置的 bean 的信息加载到内存中,以 BeanDefinition 对象的形式存放,该对象中存放了 bean 的相关属性,下面就以 debug 的形式一步步来看下 bean 是如何创建的。

Spring 中 bean 的创建可以说是非常的复杂,方法嵌套很多,为了更好的理清创建过程,画了下面的 UML 图:

从上述 UML 图中,可以看出 bean 的创建主要分为以下几步:

1. 根据 bean 的 name 解析对应的 class
2. 处理 lookup-metod 和 replace-method 子标签
3. 处理初始化前的后置处理器
4. 真正的创建 bean 
    4.1 创建 bean 实例
        4.1.1 工厂方法创建
        4.1.2 带参数的构造方法创建
        4.1.3 默认的构造方法创建
    4.2 
    4.3 添加单例对象的工厂缓存
    4.4 填充对象的各种属性
        4.4.1 名称注入
        4.4.2 类型注入
    4.5 处理 init-method 方法
        4.5.1 处理 bean 的前置处理器
        4.5.2 执行 init-method 方法
        4.5.3 处理 bean 的后置处理器

创建过程

创建 bean 的代码是在 AbstractAutowireCapableBeanFactory 类中开始创建的,在分析的过程中,会把一些代码省略掉,如异常处理等:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    // 表示 <bean> 标签,里面有各种属性
	RootBeanDefinition mbdToUse = mbd;
    // 根据设置的 class 属性或 className 来解析 class,
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}
    // 处理 lookup-method 和 replace-method 子标签
	mbdToUse.prepareMethodOverrides();
	
    // 给 BeanPostProcessors 机会返回一个代理来代替bean的实例
	// 即在初始化前,应用后置处理器,解析指定的bean是否存在初始化前的短路操作
	Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	if (bean != null) {
		return bean;
	}	
    // 创建 bean 
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);	
	return beanInstance;
}

处理 lookup-method 和 replace-method 子标签

这两个标签虽然不常用,但是是很有用的,这里不再细说;在 Spring 中 bean 注册的源码解析 中 这两个标签会被解析放到 BeanDefinition 对象的 methodOverrides 属性中,表示需要覆盖的方法;所以在创建 bean 之前需要解析这两个标签,但是只是预处理:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
	// Check that lookup methods exists.
	MethodOverrides methodOverrides = getMethodOverrides();
	if (!methodOverrides.isEmpty()) {
		Set<MethodOverride> overrides = methodOverrides.getOverrides();
		synchronized (overrides) {
			for (MethodOverride mo : overrides) {
				prepareMethodOverride(mo);
			}
		}
	}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    // 获取对应类的方法的个数
	int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
	if (count == 0) {
		throw new BeanDefinitionValidationException("...");
	}
    // 标记 MethodOverride 未被覆盖,避免了后面参数类型检查的开销
	else if (count == 1) {
		mo.setOverloaded(false);
	}
}

在处理 prepareMethodOverride (MethodOverride mo) 方法为什么只处理方法个数为 1 的情况呢?如果一个类中有多个重载的方法,则调用或增强的时候,还需要进行参数类型的解析才能确定调用的是哪个方法,Spring 把部分功能放在这里提前进行预处理,如果方法只有一个,即没有重载的方法,在后面调用的时候,直接找到该方法调用,不用再去解析参数来确定方法了,这样就可以避免的一些参数类型检查的开销。

实例化的前置处理

如果经过前置处理后的结果不为空,则直接返回,不再进行 bean 的创建过程,AOP 功能就是在这里判断的:

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
	return bean;
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
                // bean 的前置处理器
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
                    // bean 的后置处理器
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

创建 bean 

当经过 resolveBeforeInstantiation 方法后,如果程序创建了代理,或者执行了 applyBeanPostProcessorsBeforeInstantiation 和 applyBeanPostProcessorsAfterInitialization 方法后,bean 被改变了,则直接返回,否则,会进行创建 bean 操作:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {

	// 最终返回的 bean 的包装类
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
        // 如果是单例,则检查工厂缓存中以前是否创建过
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
        // 创建bean,工厂方法创建,构造方法创建,默认构造方法创建等
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
	mbd.resolvedTargetType = beanType;

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			// 应用 MergedBeanDefinitionPostProcessors
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			mbd.postProcessed = true;
		}
	}
	// 检查循环依赖:是否是单例 && 是否允许循环依赖 && 当前bean是否正在创建中
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		// 为了避免后期的循环依赖,在bean初始化完成前,将创建bean的工厂添加到缓存中,如果其他的bean依赖该bean,直接从缓存中获取对应的工厂创建集合,解决循环依赖,注意是只有单例情况才能这么做
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}
	// 初始化 bean
	Object exposedObject = bean;
    // 填充属性
	populateBean(beanName, mbd, instanceWrapper);
	if (exposedObject != null) {
        // 执行初始化方法,如 init-method 
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	if (earlySingletonExposure) {
        // 只有在检测到循环依赖时才不会为空
		Object earlySingletonReference = getSingleton(beanName, false);
        // 存在循环依赖
		if (earlySingletonReference != null) {
           // 如果 exposedObject 在初始化方法中没有被改变,即没有被增强
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<String(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
                    // 检测依赖
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
                // 因为bean创建后,所依赖的bean一定是已经创建完毕的,actualDependentBeans 不为空则表示所依赖的bean还没有创建完,即存在循环依赖
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException("");
				}
			}
		}
	}
    // 根据 score 注册 bean 
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
	return exposedObject;
}

上面创建 bean 的过程很复杂,分为很多步骤,下面再来看看这些步骤:

创建 bean 实例

创建 bean 的实例,会根据策略使用不同的创建方法,比如说 构造方法创建, 工厂方法创建,默认的构造方法创建等:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 获取 bean 对应的 class 
	Class<?> beanClass = resolveBeanClass(mbd, beanName);
    // 如果工厂方法不为空,则使用工厂方法创建
	if (mbd.getFactoryMethodName() != null)  {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
            // 一个类有多个构造方法,带有不同的参数,所以调用前,需要根据参数解析出需要调用的构造方法,
            // 这里使用了缓存,如果以前解析过构造方法,则在这里直接使用即可。
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
		if (autowireNecessary) {
            // 构造方法自动注入
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
            // 默认构造方法自动注入
			return instantiateBean(beanName, mbd);
		}
	}
	// 解析构造方法
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        // 构造方法自动注入
		return autowireConstructor(beanName, mbd, ctors, args);
	}
    // 默认构造方法自动注入
	return instantiateBean(beanName, mbd);
}

参数的构造方法注入

先来看下带参数的构造方法自动注入,

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
		Constructor<?>[] chosenCtors, final Object[] explicitArgs) {

	BeanWrapperImpl bw = new BeanWrapperImpl();
	this.beanFactory.initBeanWrapper(bw);

	Constructor<?> constructorToUse = null;
	ArgumentsHolder argsHolderToUse = null;
	Object[] argsToUse = null;
    // explicitArgs 参数通过 getBean() 方法传入,Object getBean(String name, Object... args)
	if (explicitArgs != null) {
        // 如果 getBean 方法传入了参数,则直接使用
		argsToUse = explicitArgs;
	}
	else {
        // 如果 getBean 方法没有传入参数,则从配置文件进行解析
		Object[] argsToResolve = null;
        // 从缓存中获取
		synchronized (mbd.constructorArgumentLock) {
			constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
			if (constructorToUse != null && mbd.constructorArgumentsResolved) {
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		if (argsToResolve != null) {
            // 配置的构造方法参数
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
		}
	}
    // 该构造没有被缓存,则需要进行解析
	if (constructorToUse == null) {
		boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
		ConstructorArgumentValues resolvedValues = null;
        // 参数个数
		int minNrOfArgs;
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
            // 获取配置文件中配置的构造方法参数
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			resolvedValues = new ConstructorArgumentValues();
            // 获取参数个数
		    minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}
		Constructor<?>[] candidates = chosenCtors;
		if (candidates == null) {
			Class<?> beanClass = mbd.getBeanClass();
			candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors());
		}
        // 排序构造方法,按照参数个数进行排序
		AutowireUtils.sortConstructors(candidates);
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Constructor<?>> ambiguousConstructors = null;
		for (Constructor<?> candidate : candidates) {
			Class<?>[] paramTypes = candidate.getParameterTypes();
			if (constructorToUse != null && argsToUse.length > paramTypes.length) {
				// 如果已经找到满足条件的构造方法,则终止
				break;
			}
			if (paramTypes.length < minNrOfArgs) {
				continue;
			}
			ArgumentsHolder argsHolder;
			if (resolvedValues != null) {
                // 构造方法参数的名字
				String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
			    if (paramNames == null) {
                    // 如果参数名字为空,则获取参数名称探索器
					ParameterNameDiscoverer pnd=this.beanFactory.getParameterNameDiscoverer();
					if (pnd != null) {
                        // 使用探索器获取对应构造方法的参数名称
					   paramNames = pnd.getParameterNames(candidate);
					}
                    // 根据参数名称和类型创建参数持有者
				argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,getUserDeclaredConstructor(candidate), autowiring);
			}
			else {
				// 构造方法没有参数
				argsHolder = new ArgumentsHolder(explicitArgs);
			}
            // 检查是否有不确定性构造方法的存在,如参数为父子关系
			int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
			if (typeDiffWeight < minTypeDiffWeight) {
				constructorToUse = candidate;
				argsHolderToUse = argsHolder;
				argsToUse = argsHolder.arguments;
				minTypeDiffWeight = typeDiffWeight;
				ambiguousConstructors = null;
			}
			else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
				if (ambiguousConstructors == null) {
					ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
					ambiguousConstructors.add(constructorToUse);
				}
				ambiguousConstructors.add(candidate);
			}
		}

		if (constructorToUse == null) {
			throw new BeanCreationException("...")
		}
        // 将解析的构造方法加入缓存
		if (explicitArgs == null) {
			argsHolderToUse.storeCache(mbd, constructorToUse);
		}
	}
    // 实例化
	Object beanInstance;
	if (System.getSecurityManager() != null) {
		final Constructor<?> ctorToUse = constructorToUse;
		final Object[] argumentsToUse = argsToUse;
		beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
			public Object run() {
				return beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
			}
		}, beanFactory.getAccessControlContext());
	}
	else {
		beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
				mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
	}
	bw.setBeanInstance(beanInstance);
	return bw;
}

上面的方法就是使用构造方法进行实例化 bean 的过程,很复杂,也有很多的辅助方法,下面来看下实例化的过程:

实例化有两种方式,CGLIB 和 反射:

beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, beanFactory, ctorToUse);

先来看下 getInstantiationStrategy 方法返回什么?

protected InstantiationStrategy getInstantiationStrategy() {
	return this.instantiationStrategy;
}
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

它返回的是 InstantiationStrategy  接口,而接口由两个实现类:

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
		final Constructor<?> ctor, Object... args) {
    // 如果没有需要动态改变的方法,则直接使用反射进行实例化
	if (bd.getMethodOverrides().isEmpty()) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					ReflectionUtils.makeAccessible(ctor);
					return null;
				}
			});
		}
        // 使用 反射 实例化
		return BeanUtils.instantiateClass(ctor, args);
	}
	else {
        // 如果需要覆盖或者动态替换的方法,则需要使用 CGLIB 来动态代理,在创建代理的时候,可以增强植入我们的代码
		return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
	}
}

使用工厂方法创建实例和构造方法参不多,使用默认的构造方法实例化比较简单,这里就不列出来了。

属性填充

在上面分析  doCreateBean 方法的时候,当通过 工厂方法,带参数的构造方法或默认的构造方法创建了 bean 实例后,需要对 bean 的属性进行设置

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	PropertyValues pvs = mbd.getPropertyValues();
    // 给 InstantiationAwareBeanPostProcessor 最后一次机会在属性设置前来改变 bean 
	boolean continueWithPropertyPopulation = true;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // postProcessAfterInstantiation 返回值为是否继续填充 bean 
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
	if (!continueWithPropertyPopulation) {
		return;
	}

	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // 名称注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
        // 类型注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}
    // 后处理器已经初始化
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 需要依赖检查
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
	if (hasInstAwareBpps || needsDepCheck) {
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
		   for (BeanPostProcessor bp : getBeanPostProcessors()) {
			  if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 对所有需要依赖检查的属性进行后置处理
				pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(),beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}
    // 将属性应用到 bean 中
	applyPropertyValues(beanName, mbd, bw, pvs);
}

关于 名称 注入和类型注入,后面单独分析

将属性应用到 bean 中:

到这里,已经完成了对注入属性的获取,但是获取的是 PropereyValues 的形式存在,现在将他们应用到 bean 中去:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	if (pvs == null || pvs.isEmpty()) {
		return;
	}
	if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
		((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
	}
	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;
	if (pvs instanceof MutablePropertyValues) {
        // 如果 mpvs 中的值已经被转换为对应的类型,则可以直接设置到 beanWapper 中 
		mpvs = (MutablePropertyValues) pvs;
		if (mpvs.isConverted()) {
			bw.setPropertyValues(mpvs);
			return;
		}
		original = mpvs.getPropertyValueList();
	}
	else {
        // 如果 pvs 不是 MutablePropertyValues 封装的类,则直接使用原始的属性获取方法
		original = Arrays.asList(pvs.getPropertyValues());
	}
    // 获取用户自定义的类型转换器
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
    / 获取对应的解析器
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
	boolean resolveNecessary = false;
    // 遍历属性,将属性转换为对应类的对应属性的类型
	for (PropertyValue pv : original) {
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			if (convertible) {
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
			if (resolvedValue == originalValue) {
				if (convertible) {
					pv.setConvertedValue(convertedValue);
				}
				deepCopy.add(pv);
			}
			else if (convertible && originalValue instanceof TypedStringValue &&
				!((TypedStringValue) originalValue).isDynamic() &&
				!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
				pv.setConvertedValue(convertedValue);
				deepCopy.add(pv);
			}
			else {
				resolveNecessary = true;
				deepCopy.add(new PropertyValue(pv, convertedValue));
			}
		}
	}
	if (mpvs != null && !resolveNecessary) {
		mpvs.setConverted();
	}
	bw.setPropertyValues(new MutablePropertyValues(deepCopy));

}

执行初始化方法

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    // 执行用户自定义的各种 aware 方法
	invokeAwareMethods(beanName, bean);

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
        // 在执行 init 方法之前,先执行 前置处理器 applyBeanPostProcessorsBeforeInitialization
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
    // 执行初始化方法
	invokeInitMethods(beanName, wrappedBean, mbd);

    // 执行后置处理器 applyBeanPostProcessorsAfterInitialization
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}
// 执行用户自定义的各种 aware 方法 
private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
		}
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

到这里,bean 创建的大致过程就结束了

 

spring beans源码解读之--bean definiton解析器

spring beans源码解读之--bean definiton解析器

spring提供了有两种方式的bean definition解析器:PropertiesBeanDefinitionReader和XmLBeanDefinitionReader即属性文件格式的bean definition解析器和xml文件格式的bean definition解析器。

我们先从简单的PropertiesBeanDefinitionReader开始深入挖掘。

1. PropertiesBeanDefinitionReader 属性文件bean definition解析器

 1.1  作用:一种简单的属性文件格式的bean definition解析器,提供以Map/Properties类型ResourceBundle类型定义的bean的注册方法。例如:

复制代码

employee.(class)=MyClass       // bean is of class MyClass
 employee.(abstract)=true       // this bean can''t be instantiated directly
 employee.group=Insurance       // real property
 employee.usesDialUp=false      // real property (potentially overridden)

 salesrep.(parent)=employee     // derives from "employee" bean definition
 salesrep.(lazy-init)=true      // lazily initialize this singleton bean
 salesrep.manager(ref)=tony     // reference to another bean
 salesrep.department=Sales      // real property

 techie.(parent)=employee       // derives from "employee" bean definition
 techie.(scope)=prototype       // bean is a prototype (not a shared instance)
 techie.manager(ref)=jeff       // reference to another bean
 techie.department=Engineering  // real property
 techie.usesDialUp=true         // real property (overriding parent value)

 ceo.$0(ref)=secretary          // inject ''secretary'' bean as 0th constructor arg
 ceo.$1=1000000                 // inject value ''1000000'' at 1st constructor arg

复制代码

1.2 层次结构

public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader {
}

public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {
}

其中:

EnvironmentCapable接口是一个包含和暴露Enviroment引用的组件。所有的spring的application context都继承了EnvironmentCapable接口,这个接口的主要用来在框架中使用instanceof方法检测,为了和enviroment进行交互,instanceof方法用来检查beanFactory实例是否是applicationContext实例。
像说明提到到,applicationContext继承了EnvironmentCapable接口,因此暴露了一个getEnviroment()方法,ConfigurableApplicationContext重写了getEnviroment方法,返回了一个ConfigurableEnviroment。
BeanDefinitionReader接口定义了bean definition 解析器的基本方法,特别是使用resource来加载bean definition的方法。

1.3 抽象bean definition解析器AbstractBeanDefinitionReader 

1.3.1 EnvironmentCapable接口只有一个方法getEnviroment(),其实现如下:

复制代码

// Inherit Environment if possible
        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
        }
        else {
            this.environment = new StandardEnvironment();
        }

复制代码

当实现了BeanDefinitionRegistry接口的beanFactory同时实现了EnvironmentCapable接口,则直接使用该beanfactory的getEnviroment()方法,否则使用默认的标准Enviroment。

其中,StandardEnvironment类实现了Enviroment接口,适用于标准的应用(例如非web应用)。该接口还通过AbstractEnvironment接口间接继承ConfigurableEnvironment接口,故具有ConfigurableEnvironment接口的功能:属性解析和profile相关操作。同时该类还配置了两个默认属性源,按照查询顺序如下:

系统属性,系统环境变量。

这就是说,若键"xyz" 即是当前进程的jvm的系统属性也是系统环境变量,则键值则是从系统属性中获取(environment.getProperty("xyz")). 这种顺序安排是系统默认的,因为系统属性优先于jvm,而系统环境变量则可以在给定系统的多个jvm中共享。系统属性优先允许对不同jvm的环境变量进行定制。

 1.3.2 BeanDefinitionReader接口实现方法

BeanDefinitionReader接口提供了标准的解析器方法: 

ClassLoader getBeanClassLoader() 返回加载bean类型(classes)的class loader。
BeanNameGenerator getBeanNameGenerator() 返回匿名bean(没有指明name的bean)的BeanNameGenerator. 
BeanDefinitionRegistry getRegistry()返回注册bean definition的beanFactory. 
ResourceLoader getResourceLoader()返回指定资源位置的 resource loader. 
int loadBeanDefinitions(Resource... resources) 根据指定的多个资源加载bean definition. 
int loadBeanDefinitions(Resource resource) 根据指定的一个资源加载bean definition.
int loadBeanDefinitions(String... locations) 根据指定的多个资源位置加载. 
int loadBeanDefinitions(String location) 根据指定的一个资源位置加载bean definition.

其中,BeanDefinitionRegistry是构造函数传入的,resourceloader获取:

复制代码

// Determine ResourceLoader to use.
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader) this.registry;
        }
        else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }

复制代码

其中最重要的方法是根据特定资源的位置来加载bean definiton

复制代码

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
        ResourceLoader resourceLoader = getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException(
                    "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
        }

        if (resourceLoader instanceof ResourcePatternResolver) {
            // Resource pattern matching available.
            try {
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                int loadCount = loadBeanDefinitions(resources);
                if (actualResources != null) {
                    for (Resource resource : resources) {
                        actualResources.add(resource);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                }
                return loadCount;
            }
            catch (IOException ex) {
                throw new BeanDefinitionStoreException(
                        "Could not resolve bean definition resource pattern [" + location + "]", ex);
            }
        }
        else {
            // Can only load single resources by absolute URL.
            Resource resource = resourceLoader.getResource(location);
            int loadCount = loadBeanDefinitions(resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }
            return loadCount;
        }
    }

复制代码

这个方法既支持url绝对路径的单个资源加载,也支持正则表达式的模式匹配资源加载。其中loadBeanDefinitions()放到子类去执行,在PropertiesBeanDefinitionReader中我们可以看到使用属性文件中去读取(具体细节就不赘叙了),请自行参考代码:

复制代码

public int loadBeanDefinitions(EncodedResource encodedResource, String prefix)
            throws BeanDefinitionStoreException {

        Properties props = new Properties();
        try {
            InputStream is = encodedResource.getResource().getInputStream();
            try {
                if (encodedResource.getEncoding() != null) {
                    getPropertiesPersister().load(props, new InputStreamReader(is, encodedResource.getEncoding()));
                }
                else {
                    getPropertiesPersister().load(props, is);
                }
            }
            finally {
                is.close();
            }
            return registerBeanDefinitions(props, prefix, encodedResource.getResource().getDescription());
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException("Could not parse properties from " + encodedResource.getResource(), ex);
        }
    }

复制代码

XmlBeanDefinitionReader 读取bean definition属性通过特定的xml文件(具体细节就不赘叙了,请自行参考代码),如下所示:

复制代码

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

        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet<EncodedResource>(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }
        if (!currentResources.add(encodedResource)) {
            throw new BeanDefinitionStoreException(
                    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        }
        try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            finally {
                inputStream.close();
            }
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "IOException parsing XML document from " + encodedResource.getResource(), ex);
        }
        finally {
            currentResources.remove(encodedResource);
            if (currentResources.isEmpty()) {
                this.resourcesCurrentlyBeingLoaded.remove();
            }
        }
    }

复制代码

1.4 根据给定前缀,读取所有属性并根据名称将bean增加到bean factory之中。

复制代码

protected void registerBeanDefinition(String beanName, Map<?, ?> map, String prefix, String resourceDescription)
            throws BeansException {

        String className = null;
        String parent = null;
        String scope = GenericBeanDefinition.SCOPE_SINGLETON;
        boolean isAbstract = false;
        boolean lazyInit = false;

        ConstructorArgumentValues cas = new ConstructorArgumentValues();
        MutablePropertyValues pvs = new MutablePropertyValues();

        for (Map.Entry<?, ?> entry : map.entrySet()) {
            String key = StringUtils.trimWhitespace((String) entry.getKey());
            if (key.startsWith(prefix + SEPARATOR)) {
                String property = key.substring(prefix.length() + SEPARATOR.length());
                if (CLASS_KEY.equals(property)) {
                    className = StringUtils.trimWhitespace((String) entry.getValue());
                }
                else if (PARENT_KEY.equals(property)) {
                    parent = StringUtils.trimWhitespace((String) entry.getValue());
                }
                else if (ABSTRACT_KEY.equals(property)) {
                    String val = StringUtils.trimWhitespace((String) entry.getValue());
                    isAbstract = TRUE_VALUE.equals(val);
                }
                else if (SCOPE_KEY.equals(property)) {
                    // Spring 2.0 style
                    scope = StringUtils.trimWhitespace((String) entry.getValue());
                }
                else if (SINGLETON_KEY.equals(property)) {
                    // Spring 1.2 style
                    String val = StringUtils.trimWhitespace((String) entry.getValue());
                    scope = ((val == null || TRUE_VALUE.equals(val) ? GenericBeanDefinition.SCOPE_SINGLETON :
                            GenericBeanDefinition.SCOPE_PROTOTYPE));
                }
                else if (LAZY_INIT_KEY.equals(property)) {
                    String val = StringUtils.trimWhitespace((String) entry.getValue());
                    lazyInit = TRUE_VALUE.equals(val);
                }
                else if (property.startsWith(CONSTRUCTOR_ARG_PREFIX)) {
                    if (property.endsWith(REF_SUFFIX)) {
                        int index = Integer.parseInt(property.substring(1, property.length() - REF_SUFFIX.length()));
                        cas.addIndexedArgumentValue(index, new RuntimeBeanReference(entry.getValue().toString()));
                    }
                    else {
                        int index = Integer.parseInt(property.substring(1));
                        cas.addIndexedArgumentValue(index, readValue(entry));
                    }
                }
                else if (property.endsWith(REF_SUFFIX)) {
                    // This isn''t a real property, but a reference to another prototype
                    // Extract property name: property is of form dog(ref)
                    property = property.substring(0, property.length() - REF_SUFFIX.length());
                    String ref = StringUtils.trimWhitespace((String) entry.getValue());

                    // It doesn''t matter if the referenced bean hasn''t yet been registered:
                    // this will ensure that the reference is resolved at runtime.
                    Object val = new RuntimeBeanReference(ref);
                    pvs.add(property, val);
                }
                else {
                    // It''s a normal bean property.
                    pvs.add(property, readValue(entry));
                }
            }
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Registering bean definition for bean name ''" + beanName + "'' with " + pvs);
        }

        // Just use default parent if we''re not dealing with the parent itself,
        // and if there''s no class name specified. The latter has to happen for
        // backwards compatibility reasons.
        if (parent == null && className == null && !beanName.equals(this.defaultParentBean)) {
            parent = this.defaultParentBean;
        }

        try {
            AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
                    parent, className, getBeanClassLoader());
            bd.setScope(scope);
            bd.setAbstract(isAbstract);
            bd.setLazyInit(lazyInit);
            bd.setConstructorArgumentValues(cas);
            bd.setPropertyValues(pvs);
            getRegistry().registerBeanDefinition(beanName, bd);
        }
        catch (ClassNotFoundException ex) {
            throw new CannotLoadBeanClassException(resourceDescription, beanName, className, ex);
        }
        catch (LinkageError err) {
            throw new CannotLoadBeanClassException(resourceDescription, beanName, className, err);
        }
    }

复制代码

其中,bean definition中所有属性如下:

static String ABSTRACT_KEY

Special key to distinguish owner.(abstract)=true Default is "false".

static String CLASS_KEY

Special key to distinguish owner.(class)=com.myapp.MyClass-

static String CONSTRUCTOR_ARG_PREFIX

Prefix used to denote a constructor argument definition.

static String LAZY_INIT_KEY

Special key to distinguish owner.(lazy-init)=true Default is "false".

static String PARENT_KEY

Special key to distinguish owner.(parent)=parentBeanName.

static String REF_PREFIX

Prefix before values referencing other beans.

static String REF_SUFFIX

Property suffix for references to other beans in the current BeanFactory: e.g.

static String SCOPE_KEY

Special key to distinguish owner.(scope)=prototype.

static String SEPARATOR

Separator between bean name and property name.

static String SINGLETON_KEY

Special key to distinguish owner.(singleton)=false.

static String TRUE_VALUE

Value of a T/F attribute that represents true.

 

2. XmlBeanDefinitionReader解析器和PropertiesBeanDefinitionReader解析器基本相同,但在获取bean definition(上面已经论述过)和bean 的注册时不同的。

其真正实现如下代码所示:

复制代码

/**
     * Register each bean definition within the given root {@code <beans/>} element.
     */
    protected void doRegisterBeanDefinitions(Element root) {
        String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
        if (StringUtils.hasText(profileSpec)) {
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {
                return;
            }
        }

        // Any nested <beans> elements will cause recursion in this method. In
        // order to propagate and preserve <beans> default-* attributes correctly,
        // keep track of the current (parent) delegate, which may be null. Create
        // the new (child) delegate with a reference to the parent for fallback purposes,
        // then ultimately reset this.delegate back to its original (parent) reference.
        // this behavior emulates a stack of delegates without actually necessitating one.
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(this.readerContext, root, parent);

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

        this.delegate = parent;
    }

复制代码

3. 小结

spring提供了有两种方式的bean definition解析器:PropertiesBeanDefinitionReader和XmLBeanDefinitionReader即属性文件格式的bean definition解析器和xml文件格式的bean definition解析器。

不同有两点:

1. 根据Resource 加载 bean definition。PropertiesBeanDefinitionReader从属性文件中读取bean definition的属性,XmLBeanDefinitionReader从xml文件中读取bean definition的属性。

2. 注册bean definition。和加载bean definitino类同,只是方式不同。

Spring IoC 源码解析之 getBean

Spring IoC 源码解析之 getBean

一、实例化所有的非懒加载的单实例 Bean

  从 org.springframework.context.support.AbstractApplicationContext#refresh 方法开发,进入到实例化所有的非懒加载的单实例 Bean 的 finishBeanFactoryInitialization (beanFactory) 的方法:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 为Bean工厂设置类型转化器
        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(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return 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);

        //冻结所有的Bean定义 , 至此注册的Bean定义将不被修改或任何进一步的处理
        beanFactory.freezeConfiguration();

        //实例化剩下的单实例Bean
        beanFactory.preInstantiateSingletons();
    }

  进入实例化剩下的单实例 Bean 的 beanFactory.preInstantiateSingletons () 的方法:

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

        //获取我们容器中所有Bean定义的名称
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        //循环我们所有的bean定义名称
        for (String beanName : beanNames) {
            //合并我们的bean定义
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //根据bean定义判断是不是抽象的 && 不是单例的 && 不是懒加载的
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //是否FactoryBean
                if (isFactoryBean(beanName)) {
                    //是 给beanName+前缀 & 符号
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        //调用真正的getBean
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {//非工厂Bean就是普通的bean
                    getBean(beanName);
                }
            }
        }

        //获取所有的bean的名称 至此所有的单实例的bean已经加入到单实例Bean的缓存池中,所谓的单实例缓存池实际上就是一个ConcurrentHashMap
        for (String beanName : beanNames) {
            //从单例缓存池中获取所有的对象
            Object singletonInstance = getSingleton(beanName);
            //判断当前的bean是否实现了SmartInitializingSingleton接口
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    //触发实例化之后的方法afterSingletonsInstantiated
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

  前面多个地方涉及到 getBean,接下来就分析下 getBean(很重要

二、getBean 流程

  进入 getBean (beanName) 的方法:

@Override
    public Object getBean(String name) throws BeansException {
        //真正的获取Bean的逻辑
        return doGetBean(name, null, null, false);
    }

  该方法啥没干,又交给了干活的 doGetBean (name, null, null, false) 方法:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        //在这里传入进来的name可能是别名、也有可能是工厂beanName,所以在这里需要转换
        final String beanName = transformedBeanName(name);
        Object bean;

        //先尝试去缓存中获取对象
        Object sharedInstance = getSingleton(beanName);

        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean ''" + beanName +
                            "'' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean ''" + beanName + "''");
                }
            }
            /**
             * 如果sharedInstance是普通的单例bean,下面的方法会直接返回。但如果
             * sharedInstance是FactoryBean类型的,则需调用getObject工厂方法获取真正的
             * bean实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
             * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
             */
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {

            //Spring只能解决单例对象的setter注入的循环依赖,不能解决构造器注入,也不能解决多实例的循环依赖
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            //判断是否有父工厂
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //若存在父工厂,切当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFactory中
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                //获取bean的原始名称
                String nameToLookup = originalBeanName(name);
                //若为AbstractBeanFactory类型,委托父类处理
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // 委托给构造函数getBean()处理
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // 没有args,委托给标准的getBean()处理
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            /**
             * 方法参数typeCheckOnly ,是用来判断调用getBean(...) 方法时,表示是否为仅仅进行类型检查获取Bean对象
             * 如果不是仅仅做类型检查,而是创建Bean对象,则需要调用markBeanAsCreated(String beanName) 方法,进行记录
             */
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //从容器中获取beanName相应的GenericBeanDefinition对象,并将其转换为RootBeanDefinition对象
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //检查当前创建的bean定义是不是抽象的bean定义
                checkMergedBeanDefinition(mbd, beanName, args);

                //处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
                //依赖bean的名称
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        //beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between ''" + beanName + "'' and ''" + dep + "''");
                        }
                        //保存的是依赖beanName之间的映射关系:依赖beanName -> beanName的集合
                        registerDependentBean(dep, beanName);
                        try {
                            //获取dependsOn的bean
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "''" + beanName + "'' depends on missing bean ''" + dep + "''", ex);
                        }
                    }
                }

                //是单例则创建单例Bean
                if (mbd.isSingleton()) {
                    //把beanName和一个singletonFactory匿名内部类传入用于回调
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //创建bean的逻辑
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            //创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                else if (mbd.isPrototype()) {
                    // It''s a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    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;
            }
        }

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

  第一步:先尝试去缓存中获取对象

  Object sharedInstance = getSingleton (beanName),由于第一次肯定为空:

public Object getSingleton(String beanName) {
        //在这里系统一般是允许早期对象引用的allowEarlyReference通过这个参数可以控制解决循环依赖
        return getSingleton(beanName, true);
    }

  进入到 getSingleton (beanName, true) 方法,这里涉及到 Spring 的三级缓存,用它来解决循环依赖:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        /**
         * 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的)
         * Spring IoC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
         */
        Object singletonObject = this.singletonObjects.get(beanName);
        /**
         * 若在第一级缓存中没有获取到对象,并且singletonsCurrentlyInCreation正在创建的单实例的list包含该beanName
         * Spring IoC容器初始化加载单实例bean的时候第一次进来的时候 该list中一般返回空,但是循环依赖的时候可以满足该条件
         */
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                /**
                 * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
                 * 何为早期对象:就是bean刚刚调用了构造方法,还没给bean的属性进行赋值的对象就是早期对象
                 */
                singletonObject = this.earlySingletonObjects.get(beanName);
                /**
                 * 二级缓存中也没有获取到对象,allowEarlyReference为true(参数是有上一个方法传递进来的true)
                 */
                if (singletonObject == null && allowEarlyReference) {
                    /**
                     * 直接从三级缓存中获取ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在
                     * 在getBean的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory暴露到三级缓存中
                     */
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    //从三级缓存中获取到对象不为空
                    if (singletonFactory != null) {
                        /**
                         * 在这里通过暴露的ObjectFactory包装对象中,通过调用他的getObject()来获取我们的早期对象
                         * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
                         */
                        singletonObject = singletonFactory.getObject();
                        //把早期对象放置在二级缓存,
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //ObjectFactory 包装对象从三级缓存中删除掉
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

  第二步:走 else 逻辑

  Spring 只能解决单例对象的 setter 注入的循环依赖,不能解决构造器注入,也不能解决多实例的循环依赖,所以会抛 Bean 当前正在创建的异常,接着判断是否有父工厂,有就调用父工厂的 getBean,如果不是仅仅做类型检查,而是创建 Bean 对象,则需要调用 markBeanAsCreated 方法进行标识

  合并 Bean 定义信息

  ① 接着调用 getMergedLocalBeanDefinition (beanName) 进行 Bean 定义的合并方法如下:

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        // 快速从缓存中获取,如果不为空,则直接返回
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null) {
            return mbd;
        }
        //获取 RootBeanDefinition 对象。若获取的 BeanDefinition 为子 BeanDefinition,则需要合并父类的相关属性.
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }

  ② 进入到 getMergedBeanDefinition (beanName, getBeanDefinition (beanName)) 方法:

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
            throws BeanDefinitionStoreException {
        //调用重载的方法
        return getMergedBeanDefinition(beanName, bd, null);
    }

  ③ 进入到 getMergedBeanDefinition (beanName, bd, null) 的方法:

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

        //加锁
        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;

            // Check with full lock now in order to enforce the same merged instance.
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }

            if (mbd == null) {
                //bd.getParentName() == null,表明无父配置,这时直接将当前的BeanDefinition升级为RootBeanDefinition
                if (bd.getParentName() == null) {
                    //直接把原始的bean定义升级为RootBeanDefinition
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        //包裹为RootBeanDefinition
                        mbd = new RootBeanDefinition(bd);
                    }
                }
                //有父定义
                else {
                    BeanDefinition pbd;
                    try {
                        /*
                         * 判断父类beanName与子类beanName名称是否相同。若相同,则父类bean一定
                         * 在父容器中。原因也很简单,容器底层是用Map缓存<beanName, bean> 键值对
                         * 的。同一个容器下,使用同一个 beanName 映射两个bean实例显然是不合适的
                         */
                        String parentBeanName = transformedBeanName(bd.getParentName());
                        if (!beanName.equals(parentBeanName)) {
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            /*
                             * 这里再次调用getMergedBeanDefinition,只不过参数值变为了
                             * parentBeanName,用于合并父BeanDefinition 和爷爷辈的
                             * BeanDefinition。如果爷爷辈的BeanDefinition仍有父
                             * BeanDefinition,则继续合并
                             */
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }
                            else {
                                throw new NoSuchBeanDefinitionException(parentBeanName,
                                        "Parent name ''" + parentBeanName + "'' is equal to bean name ''" + beanName +
                                        "'': cannot be resolved without an AbstractBeanFactory parent");
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                "Could not resolve parent bean definition ''" + bd.getParentName() + "''", ex);
                    }
                    //以父BeanDefinition的配置信息为基本创建RootBeanDefinition
                    mbd = new RootBeanDefinition(pbd);
                    //用子BeanDefinition中的属性覆盖父BeanDefinition中的属性
                    mbd.overrideFrom(bd);
                }

                // 如果用户未配置scope属性,则默认将该属性配置为singleton
                if (!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope(RootBeanDefinition.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.
                if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    mbd.setScope(containingBd.getScope());
                }

                //缓存合并后的BeanDefinition
                if (containingBd == null && isCacheBeanMetadata()) {
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }

            return mbd;
        }
    }

  ④ 然后检查当前创建的 bean 定义是不是抽象的 bean 定义,checkMergedBeanDefinition (mbd, beanName, args) 方法:

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
            throws BeanDefinitionStoreException {

        //抽象的bean定义是不能够被实例化的
        if (mbd.isAbstract()) {
            throw new BeanIsAbstractException(beanName);
        }
    }

  处理 dependsOn 的依赖 (这个不是我们所谓的循环依赖 而是 bean 创建前后的依赖)

  ① 进入到 isDependent (beanName, dependentBeanName, null) 的方法:

private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
        //alreadySeen已经检测的依赖bean
        if (alreadySeen != null && alreadySeen.contains(beanName)) {
            return false;
        }
        //获取原始beanName
        String canonicalName = canonicalName(beanName);
        //获取创建当前bean所依赖的bean的名称集合
        Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
        //不依赖任何前置Bean直接返回
        if (dependentBeans == null) {
            return false;
        }
        //存在,则证明存在已经注册的依赖
        if (dependentBeans.contains(dependentBeanName)) {
            return true;
        }
        //递归检测依赖
        for (String transitiveDependency : dependentBeans) {
            if (alreadySeen == null) {
                alreadySeen = new HashSet<>();
            }
            //添加到alreadySeen 中
            alreadySeen.add(beanName);
            //递归检查依赖
            if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                return true;
            }
        }
        return false;
    }

  ② 进入到保存的是依赖 beanName 之间的映射关系:依赖 beanName -> beanName 的集合 registerDependentBean (dep, beanName) 的方法:

public void registerDependentBean(String beanName, String dependentBeanName) {
        //获取原始的beanName
        String canonicalName = canonicalName(beanName);

        // 添加 <canonicalName, dependentBeanName> 到 dependentBeanMap 中
        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                    this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
            }
        }

        // 添加 <dependentBeanName, canonicalName> 到 dependenciesForBeanMap 中
        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean =
                    this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
            dependenciesForBean.add(canonicalName);
        }
    }

  ③ 然后到获取 dependsOn 的 Bean 的 getBean (dep),就获取到了 dependsOn 的 Bean 了;

  处理单实例 Bean

  ① 把 beanName 和一个 singletonFactory 匿名内部类传入用于回调的 getSingleton 方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        //加锁
        synchronized (this.singletonObjects) {
            //尝试从单例缓存池中获取对象
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean ''" + beanName + "''");
                }
                /**
                 * 标记当前的bean马上就要被创建了
                 * singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖(构造器注入会抛出异常)
                 */
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //创建bean这个过程其实是调用 createBean() 方法
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    //回调我们singletonObjects的get方法,进行正在的创建bean的逻辑
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //后置处理主要做的事情就是把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //加入缓存中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

   第一:先到单例缓存池中获取对象获取,有就返回没有就继续往下

   第二:调用标记当前的 bean 马上就要被创建了 beforeSingletonCreation (beanName) 方法:

protected void beforeSingletonCreation(String beanName) {
        //若singletonsCurrentlyInCreation没有 则添加成功
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    

  第三:创建 Bean 的 singletonFactory.getObject () 其实是调用 createBean () 方法:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean ''" + beanName + "''");
        }
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean ''" + beanName + "''");
        }
        return beanInstance;
    }

  真正的创建我们的 bean 的实例对象的 doCreateBean (beanName, mbdToUse, args) 的方法:

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

        //BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            //从没有完成的FactoryBean中移除
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化 比较复杂也很重要
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //从beanWrapper中获取我们的早期对象
        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 {
                    //进行后置处理@AutoWired的注解的预解析
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        /**
         * 该对象进行判断是否能够暴露早期对象的条件
         * 单实例 this.allowCircularReferences 默认为true
         * isSingletonCurrentlyInCreation(表示当前的bean对象正在创建singletonsCurrentlyInCreation包含当前正在创建的bean)
         */
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        //上述条件满足,允许中期暴露对象
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean ''" + beanName +
                        "'' to allow for resolving potential circular references");
            }
            //把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,该方法内部调用getEarlyBeanReference方法
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //给我们的属性进行赋值(调用set方法进行赋值)
            populateBean(beanName, mbd, instanceWrapper);
            //进行对象初始化操作(在这里可能生成代理对象)
            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) {
            /**
             * 去缓存中获取到我们的对象 由于传递的allowEarlyReference 是false 要求只能在一级二级缓存中去获取
             * 正常普通的bean(不存在循环依赖的bean) 创建的过程中,压根不会把三级缓存提升到二级缓存中
             */
            Object earlySingletonReference = getSingleton(beanName, false);
            //能够获取到
            if (earlySingletonReference != null) {
                //经过后置处理的bean和早期的bean引用还相等的话(表示当前的bean没有被代理过)
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                //处理依赖的bean
                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 {
            //注册销毁的bean的销毁接口
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

  ① 实例化:使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化的 createBeanInstance 方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //从bean定义中解析出当前bean的class对象
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        //检测类的访问权限。默认情况下,对于非 public 的类,是允许访问的。若禁止访问,这里会抛出异常
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn''t public, and non-public access not allowed: " + beanClass.getName());
        }

        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        //工厂方法,我们通过配置类来进行配置的话 采用的就是工厂方法
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        //判断当前构造函数是否被解析过
        boolean resolved = false;
        //有没有必须进行依赖注入
        boolean autowireNecessary = false;
        /**
         * 通过getBean传入进来的构造函数是否来指定需要推断构造函数
         * 若传递进来的args不为空,那么就可以直接选出对应的构造函数
         */
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                //判断我们的bean定义信息中的resolvedConstructorOrFactoryMethod(用来缓存我们的已经解析的构造函数或者工厂方法)
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    //修改已经解析过的构造函数的标志
                    resolved = true;
                    //修改标记为ture 标识构造函数或者工厂方法已经解析过
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        //若被解析过
        if (resolved) {
            if (autowireNecessary) {
                //通过有参的构造函数进行反射调用
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //调用无参数的构造函数进行创建对象
                return instantiateBean(beanName, mbd);
            }
        }

        //通过bean的后置处理器进行选举出合适的构造函数对象
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        //通过后置处理器解析出构造器对象不为null或获取bean定义中的注入模式是构造器注入或bean定义信息ConstructorArgumentValues或获取通过getBean的方式传入的构造器函数参数类型不为null
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            //通过构造函数创建对象
            return autowireConstructor(beanName, mbd, ctors, args);
        }
        //使用无参数的构造函数调用创建对象
        return instantiateBean(beanName, mbd);
    }

  判断是否暴露早期对象条件满足就暴露早期对象,把我们的早期对象包装成一个 singletonFactory 对象 该对象提供了一个 getObject 方法,该方法内部调用 getEarlyBeanReference 方法:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        //判读我们容器中是否有InstantiationAwareBeanPostProcessors类型的后置处理器
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //获取我们所有的后置处理器
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                //判断我们的后置处理器是不是实现了SmartInstantiationAwareBeanPostProcessor接口
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    //进行强制转换
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    //挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        return exposedObject;
    }

  addSingletonFactory (beanName, () -> getEarlyBeanReference (beanName, mbd, bean)) 方法:

/**
     * 该方法用于把早期对象包装成一个ObjectFactory 暴露到三级缓存中 用于将解决循环依赖
     * @param beanName the name of the bean
     * @param singletonFactory the factory for the singleton object
     */
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        //加锁
        synchronized (this.singletonObjects) {
            //单例缓存池中没有包含当前的bean
            if (!this.singletonObjects.containsKey(beanName)) {
                //加入到三级缓存中 暴露早期对象用于解决循环依赖
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }

  ②属性赋值:给我们的属性进行赋值 (调用 set 方法进行赋值) populateBean (beanName, mbd, instanceWrapper) 方法:

/**
     *给我们的对象BeanWrapper属性赋值
     * @param beanName bean的名称
     * @param mbd bean的定义
     * @param bw bean实例包装对象
     */
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        //若bw为null的话,则说明对象没有实例化
        if (bw == null) {
            //进入if说明对象有属性,bw为空,不能为他设置属性,那就在下面就执行抛出异常
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        /**
         * 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
         * bean 状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
         * 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
         * postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。
         *当时我们发现系统中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationM没有进行任何处理,
         *若我们自己实现了这个接口 可以自定义处理.....spring 留给我们自己扩展接口的
         *特殊需求,直接使用配置中的信息注入即可。
         */
        boolean continueWithPropertyPopulation = true;
        //是否持有 InstantiationAwareBeanPostProcessor
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //获取容器中的所有的BeanPostProcessor
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                //判断我们的后置处理器是不是InstantiationAwareBeanPostProcessor
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    //进行强制转化
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //若存在后置处理器给我们属性赋值了,那么返回false 可以来修改我们的开关变量,就不会走下面的逻辑了
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        // 返回值为是否继续填充 bean
                        // postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
                        // 一般情况下,应该是返回true 。
                        // 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }
        // 如果后续处理器发出停止填充命令,则终止后续操作
        if (!continueWithPropertyPopulation) {
            return;
        }

        //获取bean定义的属性
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        /**
         * 判断我们的bean的属性注入模型
         * AUTOWIRE_BY_NAME 根据名称注入
         * AUTOWIRE_BY_TYPE 根据类型注入
         */

        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            //把PropertyValues封装成为MutablePropertyValues
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            //根据bean的属性名称注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            //根据bean的类型进行注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            //把处理过的 属性覆盖原来的
            pvs = newPvs;
        }

        /**
         * 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
         * 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
         * 而是经过后置处理器修改后的内容
         */
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        //判断是否需要检查依赖
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        if (hasInstAwareBpps || needsDepCheck) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            //提出当前正在创建的beanWrapper 依赖的对象
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                //获取所有的后置处理器
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //对依赖对象进行后置处理
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            //判断是否检查依赖
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        /**
         * 其实,上面只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues 的实例对象 pvs 中,
         * 并没有应用到已经实例化的 bean 中。而 #applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 方法,
         * 则是完成这一步骤的
         */
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

   ③初始化:进行对象初始化操作调用 initializeBean,这里会进行 Aware 接口进行方法的回调,然后调用 Bean 的后置处理器的 Before 方法(postProcessorsBeforeInitialization),然后 Bean 的初始化方法,最后调用 Bean 的后置处理器的 After 方法(PostProcessorsAfterInitialization)

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            //若我们的Bean实现了Aware接口进行方法的回调
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //调用我们的bean的后置处理器的postProcessorsBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //调用初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //调用我们bean的后置处理器的PostProcessorsAfterInitialization方法 动态代理就是在这里实现的
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

  进入调用初始化方法 invokeInitMethods (beanName, wrappedBean, mbd) 方法:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {

        //判断我们的容器中是否实现了InitializingBean接口
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking afterPropertiesSet() on bean with name ''" + beanName + "''");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //回调InitializingBean的afterPropertiesSet()方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            //我们beanClass中看是否有自己定义的init方法
            String initMethodName = mbd.getInitMethodName();
            //判断自定义的init方法名称不叫afterPropertiesSet
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //调用我们自己的初始化方法
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

  至此 doCreateBean 创建完成然后返回

  接下来 bean = getObjectForBeanInstance (sharedInstance, name, beanName, mbd),为什么不直接等于 sharedInstance,原因可能刚刚创建的 Bean 是 FactoryBean 类型的 Bean,如果是就要调用 getObject 方法来获取真正的 Bean,运用场景就是那些创建 Bean 的逻辑比较复杂的情况下可以用这个,比如 Spring 整合 Mybatis 的 SqlSessionFactoryBean

  getObjectForBeanInstance (sharedInstance, name, beanName, mbd) 方法:

protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

        // 如果name以&开头,但beanInstance却不是FactoryBean,则认为有问题。
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            }
        }

          /**
             * 如果上面的判断通过了,表明 beanInstance 可能是一个普通的 bean,也可能是一个
             * FactoryBean。如果是一个普通的 bean,这里直接返回 beanInstance 即可。如果是
             * FactoryBean,则要调用工厂方法生成一个 bean 实例。
           */
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        Object object = null;
        if (mbd == null) {
            /**
             * 如果 mbd 为空,则从缓存中加载 bean。FactoryBean 生成的单例 bean 会被缓存
             * 在 factoryBeanObjectCache 集合中,不用每次都创建
             */
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // 经过前面的判断,到这里可以保证beanInstance是 FactoryBean类型的,所以可以进行类型转换
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // 如果 mbd 为空,则判断是否存在名字为 beanName 的 BeanDefinition
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            //synthetic 字面意思是"合成的"。通过全局查找,我发现在 AOP 相关的类中会将该属性设为 true。
            //所以我觉得该字段可能表示某个 bean 是不是被 AOP 增强过,也就是 AOP 基于原始类合成了一个新的代理类。
            //不过目前只是猜测,没有深究
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            //调用 getObjectFromFactoryBean 方法继续获取实例
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }

  接着调用 object = getObjectFromFactoryBean (factory, beanName, !synthetic) 方法:

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
           /**
             * FactoryBean 也有单例和非单例之分,针对不同类型的 FactoryBean,这里有两种处理方式:
             *   1. 单例 FactoryBean 生成的 bean 实例也认为是单例类型。需放入缓存中,供后续重复使用
             *   2. 非单例 FactoryBean 生成的 bean 实例则不会被放入缓存中,每次都会创建新的实例
             **/
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                //从缓存中取bean实例,避免多次创建bean实例
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    //使用工厂对象中创建实例
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (shouldPostProcess) {
                            //判断当地的bean是否正在创建
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            beforeSingletonCreation(beanName);
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean''s singleton object failed", ex);
                            }
                            finally {
                                afterSingletonCreation(beanName);
                            }
                        }
                        // 这里的beanName对应于FactoryBean的实现类,FactoryBean的实现类也会被实例化,并被缓存在singletonObjects中
                        if (containsSingleton(beanName)) {
                            // 这里的beanName对应于FactoryBean的实现类,FactoryBean的实现类也会被实例化,并被缓存在singletonObjects中
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean''s object failed", ex);
                }
            }
            return object;
        }
    }

  使用工厂对象中创建实例 object = doGetObjectFromFactoryBean (factory, beanName) 方法:

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {

        Object object;
        try {
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //真正的调用工厂bean的getObject()方法
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }

        // Do not accept a null value for a FactoryBean that''s not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            object = new NullBean();
        }
        return object;
    }

  处理多实例 Bean

  mbd.isPrototype (),每次使用的时候再创建,因为不会加入到单实例缓冲池中,也就无法解决循环依赖问题。

  至此 doGetBean 创建完成,返回,getBean 创建完成

  最后获取所有的 bean 的名称(至此所有的单实例的 bean 已经加入到单实例 Bean 的缓存池中,所谓的单实例缓存池实际上就是一个 ConcurrentHashMap),遍历所有的 bean 名称,根据 beanName 从单例缓存池中获取所有的对象,然后判断是否是 SmartInitializingSingleton 类型,是再触发实例化之后的方法 afterSingletonsInstantiated;

  完整的 Spring IoC 源码解析见:Spring 系列(三):Spring IoC 源码解析

三、getBean 流程图

  ① getBean 流程图:

  ② @AutoWired 注入属性和 set 方法注入流程图:

 

  总结:通过对 Spring IoC 的 getBean 流程分析,了解了 Bean 的创建过程,先到单实例缓存池 (ConcurrentHashMap) 中获取,取不到就调用 createBean 创建,创建成功后加入到单实例缓存池 (ConcurrentHashMap) 中,下次获取的时候直接从 JVM 级别的缓存中获取,Bean 的生命周期,以及如何用三级缓存解决循环依赖,还有就是多实例为什么不能解决循环依赖问题。

原文出处:https://www.cnblogs.com/toby-xu/p/11333479.html

今天的关于Spring 源码解读第七弹!bean 标签的解析spring中bean标签的作用的分享已经结束,谢谢您的关注,如果想了解更多关于4.3 spring-嵌入式beans标签的解析、Spring bean 创建过程源码解析、spring beans源码解读之--bean definiton解析器、Spring IoC 源码解析之 getBean的相关知识,请在本站进行查询。

本文标签: