Spring源码分析,BeanDefinition加载过程

1.简介

Spring的启动分为关键步骤,首先是将配置文件中定义的<bean>信息加载到BeanDefintionRegistry中。然后通过BeanFactory中的getBean方法来将BeanDefinition进行实例化,开始整个bean的生命周期。

2.BeanDefinitionReader

public interface BeanDefinitionReader {
	BeanDefinitionRegistry getRegistry();//获取到对应的BeanDefinitionRegistry
	ResourceLoader getResourceLoader();//获取到ResourceLoader,为了获取对应的Resource,可以认为是一个工厂方法。
	ClassLoader getBeanClassLoader();//获取ClassLoader
	BeanNameGenerator getBeanNameGenerator();//获取到BeanName的命名
	int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;//将Resource中的Bean加载到BeanRegistry中来。
	int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
	int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;//将localtions对应的文件中定义的BeanDefinition加载并注册到BeanRegistry中来。
	int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

BeanDefinitionReader依赖了ResourceLoader,BeanDefinitionRegistry,Resource这些关键类。从接口看来loadBeanDefintions()方法,主要是将Resource中定义的Bean对象加载到BeanDefinitionRegistry中来。

3.BeanDefinition的加载过程

4.关键代码阅读

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

当前方法首先是对resource中定义的Document进行加载,校验,解析为一个Document对象。然后通过registerBeanDefinitions(doc,resource)将当前Document中的bean加载到BeanDefinitionRegistry中来。

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			Document doc = doLoadDocument(inputSource, resource);//这个过程当中主要是对当前的xml文件进行解析,校验,获取到对应的Document的对象。
			return registerBeanDefinitions(doc, resource);//这个方法是关键
		}
		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);
		}
	}

 

  4.2registerBeanDefinitions(doc, resource)

主要是讲doc中定义的<bean>等相关的信息加载到BeanDefinitionRegistry。

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();//第一步创建BeanDefinitionDocumentReader。这个是一个BeanDefinition的从Document读取的Reader。
		int countBefore = getRegistry().getBeanDefinitionCount();
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//通过BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法将Document中定义的Bean注册到registry中去。
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

当前方法将加载的任务委托给了 BeanDefinitionDocumentReader中的registerBeanDefinitions(doc, createReaderContext(resource))方法。

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		doRegisterBeanDefinitions(root);
	}

4.3BeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)

看下如何实现的:

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);//创建BeanDefinitionParseDelegate,其中对于lazy-init。auto-wire中相关的全局的默认的设置。

		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);
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isInfoEnabled()) {
						logger.info("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;
	}

4.4 parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);//这个是Spring中定义的Element的实现。
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);//用户自定义的Element类型。这里先按下不表。
		}
	}

以上方法,对于xml中定义的有Spring中默认定义的标签,也有用户自定义的标签。这里重点看下Spring自定义的标签。

4.5 parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)

看下是如何注册 系统中定义的Element的。这里是如何将Element转变为BeanRegistry中定义的BeanDefinition或者是其他相关的辅助内容的?这里是关键。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {//处理import文件。
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {//这里是 alias处理的别名
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {//这里是<bean>,这个是重点关注的。
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {//这个是嵌套的<beans>.
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

这里重点看下是如何解析<bean> 的。

4.6 processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//这里是讲一个element转变为一个BeanDefinitionHolder、
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);//BeanDefinition的额外的解析工作。
			try {
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());//将BeanDefinitionHolder注册到BeanDefinitionRegistry中去。
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));//发布一下创建的成功的事件。
		}
	}

从上面的代码可见,将一个<bean>转变为注册为注册在BeanDefinitionRegitry中的GenericBeanDefinition主要有以上的几个步骤:

第一步:通过 parseBeanDefinitionElement(ele) 将当前的<bean>转变为一个BeanDefinitionHolder。其中包括了 beanName,aliasName和GenericBeanDefinition。

第二步:通过decorateBeanDefinitionIfRequired(ele, bdHolder)方法对于BeanDefinitionHolder进行额外的处理,主要是对于<bean>中用户自定义的一些标签。

第三步:通过BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())将当前的BeanDefinitionHolder对象注册到目标BeanDefinitionRegistry中去。

第四步:将注册完成的事件发布一下事件。

 

4.6.1  parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) 

看下public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) 方法,是调用了BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)。
看下具体实现,由于<bean>配置比较的复制,可能会有省略。

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<String>();
		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) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isDebugEnabled()) {
				logger.debug("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 &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isDebugEnabled()) {
						logger.debug("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;
	}

4.6.1.1 确定beanName

确定当前的beanName和alias:首先是beanName =  id。alias = name中以“,;”分割的字符串。如果id为空,就一alias种第一个为beanName,剩余的为alias。

4.6.1.2 判断bean是否唯一

判断beanName是否被使用过。如果使用过就报错,这里对于错误的处理是值得看下的:

protected void error(String message, Element source) {
		this.readerContext.error(message, source, this.parseState.snapshot());
	}

在当前的类中有一个统一的error的方法,然后想对于异常信息的处理交给ReaderContext的error()去统一处理。这样相对比较的灵活,如果是直接抛出异常反而没有这种方式好。当然error方法最终一定要打断当前的执行进程的。

4.6.1.3 开始解析  BeanDefinition对象

AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean)。

public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {

		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {//开始处理class标签
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}

		try {
			String parent = null;//看下有没有parenet的实现。
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);//创建GenericBeanDefinition对象,主要设置parentClassName和ClassName。如果指定了ClassLoader,就将当前的class进行加载进来。

			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);//解析BeanDefinition中Attribute、
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));//设置一下description的实现。

			parseMetaElements(ele, bd);//meta属性Element
			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;
	}

看一下 在<bean>中定义的Attribute是如何解析的。这些都是定义在<bean>中的attribute,这些并不太复杂。

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
			BeanDefinition containingBean, AbstractBeanDefinition bd) {

		if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {//如果属性中有sigleton,这个时候就报错。
			error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
		}
		else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {//设置scope。
			bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
		}
		else if (containingBean != null) {//如果containBean不为空,就设置对象的scope为最新的scope。
			// Take default from containing bean in case of an inner bean definition.
			bd.setScope(containingBean.getScope());
		}

		if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {//设置当前对象为abstract对象。
			bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
		}

		String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);//设置lazy-init属性。
		if (DEFAULT_VALUE.equals(lazyInit)) {
			lazyInit = this.defaults.getLazyInit();
		}
		bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

		String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);//设置自动装配属性。		bd.setAutowireMode(getAutowireMode(autowire));

		String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);//设置  依赖自动检查
		bd.setDependencyCheck(getDependencyCheck(dependencyCheck));

		if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {//设置依赖属性
			String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
			bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
		}

		//设置 Autowire_Candidate_attribure属性,如果这个属性设置为false,这个对象将不会作为被自动装配的对象。
		//首先会使用全局的autowire_candidate_attribute的属性,然后看当前<bean>中的设置,当前<bean>中设置的优先级更高。
		String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
		if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(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));//
		}

		//当自动装配的时候,出现多个候选Bean的时候,被标记了primary属性的将会被优先的选中,否者就会抛出异常。也可以使用   Qualifier这个属性来帮助解决多个候选者的问题。
		if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
			bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
		}

		//init-method  这个方法是Spring的生命周期中的一个方法。
		//在bean中设置的init-method方法的优先级比全局的优先级高。
		if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
			String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
			if (!"".equals(initMethodName)) {
				bd.setInitMethodName(initMethodName);
			}
		}
		else {
			if (this.defaults.getInitMethod() != null) {
				bd.setInitMethodName(this.defaults.getInitMethod());
				bd.setEnforceInitMethod(false);
			}
		}

		//bean对象被销毁是将会调用的方法,和init方法一样,<bean>中定义的优先级高于 全局定义的destory方法。
		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);
			}
		}

		//这两个属性是在Spring中使用工厂方来进行管理,其中一个是factory-bean,一个是factory-method。
		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;
	}

解析完attribute后,开始解析 meta属性了。

<bean id="zandan" class="com.test.bean.meta.MetaDataBean">
   		 <meta key="metaData" value="testMataData"/>
</bean>

看下是如何解析的:

public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
		NodeList nl = ele.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {//如果当前的Node是Spring自定义的,同时== meta数据
				Element metaElement = (Element) node;
				String key = metaElement.getAttribute(KEY_ATTRIBUTE);
				String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
				BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);//创建一个BeanMetaDataAttribute的属性。
				attribute.setSource(extractSource(metaElement));
				attributeAccessor.addMetadataAttribute(attribute);//将属性添加到AttributeAccessor中去。其中BeanMetadataAttributeAccessor是GenericBeanDefinition的属性。
			}
		}
	}

其中meta数据转变为一个BeanMetadataAttribute中去。

lookup属性的解析:

 <bean id="testLookUp" class="com.test.bean.lookUp.GetBeanTest" >
    	<lookup-method name="getUser" bean="student"/>
 </bean>
 <bean id="student" class="com.test.bean.lookUp.Teacher"/>

其中在GetBeanTest中定义了一个Abstract的方法,这个方法返回一个User类型的对象。
然后在Spring的配置文件中定义一个<lookup-method name="getUser"  bean = "student">其中 bean=“student”中定义的是User类型的子类。

首先看下解析过程,将<bean>定义的look-up相关内容转变为GenericBeanDefinition中的信息中的LookupOverride的内容。

public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {//这个属性是LookUp方法。
				Element ele = (Element) node;
				String methodName = ele.getAttribute(NAME_ATTRIBUTE);
				String beanRef = ele.getAttribute(BEAN_ELEMENT);
				LookupOverride override = new LookupOverride(methodName, beanRef);//LookupOverride,这个方法是MethodOverride的子类。
				override.setSource(extractSource(ele));
				overrides.addOverride(override);//将当前的LookupOverride添加到当前系统中去。
			}
		}
	}

repleace-method的解析:

看下配置文件中的内容:

<bean id="testChangeMethod" class="com.test.bean.replace.TestChangeMethod">
    	<replaced-method name="changeMe" replacer="replacer"/>
</bean>
<bean id="replacer" class="com.test.bean.replace.TestMethodReplacer"/>

代码的实现:

public class TestChangeMethod {

    public void changeMe() {
        System.out.println("changeMe");
  	  }
	}
	
	public class TestMethodReplacer implements MethodReplacer {
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {

        System.out.println("我替换了原有的方法");
        return null;
    }
}

replace-method主要是替换当前系统中的某一个方法.其中替换方法需要实现MethodReplacer的接口。
解析的过程中,最后是将replaceMethod的定义解析为 ReplaceOverride,然后添加到BeanDefinition中的Overrides中去。

public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {//判断当前对象是replce-method标签。
				Element replacedMethodEle = (Element) node;
				String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);//获取被替换的方法。
				String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);//获取替换的bean
				ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);//创建一个替换的Override的bean,这个bean被定义为callback方法。
				// Look for arg-type match elements.
				List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
				for (Element argTypeEle : argTypeEles) {
					String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
					match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
					if (StringUtils.hasText(match)) {
						replaceOverride.addTypeIdentifier(match);
					}
				}
				replaceOverride.setSource(extractSource(replacedMethodEle));
				overrides.addOverride(replaceOverride);//将overridede方法添加到GenericBeanDefinition中去。
			}
		}
	}

构造函数的解析:
通过构造函数来构造一个Bean。其中的过程如下:

<bean id="helloBean" class="com.test.bean.construct.HelloBean">
        <constructor-arg index="0">
            <value>张三</value>
        </constructor-arg>
        <constructor-arg index="1">
            <value>你好吗?</value>
        </constructor-arg>
</bean>

HelloBen的代码如下:

public class HelloBean {

    private String name;
    private String say;

    public HelloBean(String name, String say) {
        this.name = name;
        this.say = say;
    }

    public void sayHello() {
        System.out.println(name + " : " + say);
    }

}

看下解析Bean的Constructor中信息的过程:

public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {//获取到constructor-arg的属性。
				parseConstructorArgElement((Element) node, bd);//这个是关键
			}
		}
	}

具体的实现:

public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
		String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);//根据Index来调用Constructor的Bean。
		String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);//根据Type来调用Constructor的Bean。
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);//根据Name来调用Constructor的Bean。
		if (StringUtils.hasLength(indexAttr)) {//其中index是最优先进行实例化的。
			try {
				int index = Integer.parseInt(indexAttr);
				if (index < 0) {
					error("'index' cannot be lower than 0", ele);
				}
				else {
					try {
						this.parseState.push(new ConstructorArgumentEntry(index));
						Object value = parsePropertyValue(ele, bd, null);//解析当前element中的value值。
						ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);//构造ConstructorArgumentValue属性。
						if (StringUtils.hasLength(typeAttr)) {//设置Type属性
							valueHolder.setType(typeAttr);
						}
						if (StringUtils.hasLength(nameAttr)) {//设置Name属性
							valueHolder.setName(nameAttr);
						}
						valueHolder.setSource(extractSource(ele));//设置source。
						if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {//判断当前的Index是否设置过了,如果有过,就报错。
							error("Ambiguous constructor-arg entries for index " + index, ele);
						}
						else {
							bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);//将当前的ConstructorArgumentValue写到GenericBeanDefinition中去。其中写入的是IndexArgumentValue.在实例化的时候,index的优先级也会比当前的对象高。
						}
					}
					finally {
						this.parseState.pop();
					}
				}
			}
			catch (NumberFormatException ex) {
				error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
			}
		}
		else {
			try {
				this.parseState.push(new ConstructorArgumentEntry());
				Object value = parsePropertyValue(ele, bd, null);//解析属性
				ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
				if (StringUtils.hasLength(typeAttr)) {
					valueHolder.setType(typeAttr);
				}
				if (StringUtils.hasLength(nameAttr)) {
					valueHolder.setName(nameAttr);
				}
				valueHolder.setSource(extractSource(ele));
				bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);//将当前的type和和name相关的 GenericArgumentValue写入到当前BeanDefinition中去。
			}
			finally {
				this.parseState.pop();
			}
		}
	}

Spring中属性的设置主要有三种方式,其中是 在 attribute中  设置ref。一种是在attribute中设置value。还有一种是 在Property设置 子element 的属性。

//获取property element中的 value。可能是list属性。
//也有可能使用在constructor 属性中  propertyName可能为 null。
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
		
		String elementName = (propertyName != null) ?
						"<property> element for property '" + propertyName + "'" :
						"<constructor-arg> element";//如果propertyName 为null的时候,elementName = constructor-arg。

		// Should only have one child element: ref, value, list, etc.//当前属性中应该只有一个子Element。
		NodeList nl = ele.getChildNodes();//所有的子Node属性。
		Element subElement = null;
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
					!nodeNameEquals(node, META_ELEMENT)) {
				// Child element is what we're looking for.
				if (subElement != null) {
					error(elementName + " must not contain more than one sub-element", ele);
				}
				else {
					subElement = (Element) node;
				}
			}
		}

		boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);//当前的Property中是否有ref属性
		boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);//当前Property中是否有value属性。
		if ((hasRefAttribute && hasValueAttribute) ||
				((hasRefAttribute || hasValueAttribute) && subElement != null)) {// 如果当前Property中已经有了ref或者是value,这个时候就需要报错,因为已经重复了。
			error(elementName +
					" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
		}

		if (hasRefAttribute) {//如果是在attribute中设置的ref。
			String refName = ele.getAttribute(REF_ATTRIBUTE);//获取到  ref对应的beanName。
			if (!StringUtils.hasText(refName)) {
				error(elementName + " contains empty 'ref' attribute", ele);
			}
			RuntimeBeanReference ref = new RuntimeBeanReference(refName);//构造RuntimeBeanReference。
			ref.setSource(extractSource(ele));
			return ref;//返回结果。
		}
		else if (hasValueAttribute) {
			TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
			valueHolder.setSource(extractSource(ele));
			return valueHolder;//返回TypeStringValue的值。
		}
		else if (subElement != null) {
			return parsePropertySubElement(subElement, bd);//返回解析SubElement的值。
		}
		else {
			// Neither child element nor "ref" or "value" attribute found.。如果 ref Attribute ,Value Attribute 以及  sub Element都为空的时候,这个时候就报错。
			error(elementName + " must specify a ref or value", ele);
			return null;
		}
	}

下面看下 public Object parsePropertySubElement(Element ele, BeanDefinition bd) 

public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
		if (!isDefaultNamespace(ele)) {//如果当前的属性是用户自定义的Bean信息,调用解析用户自定义的属性。
			return parseNestedCustomElement(ele, bd);
		}
		else if (nodeNameEquals(ele, BEAN_ELEMENT)) {  //如果Element是一个bean的时候。
			BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);//对当前的Bean进行解析。这个就是一个解析正常的Bean的过程。
			if (nestedBd != null) {
				nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);//对当前的Bean进行装饰
			}
			return nestedBd;//返回解析的Bean。
		}
		else if (nodeNameEquals(ele, REF_ELEMENT)) {  //如果Property中是ref类型的子Element
			//如果当前的Node是ref类型的。,主要包括  bean , ref 和  parent三种类型。对于这三种类型的实现。如果这三种 refName都为空的时候就报错误
			// A generic reference to any name of any bean.
			String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);//取出对应的Bean 的Name信息。
			boolean toParent = false;
			if (!StringUtils.hasLength(refName)) {//如果BeanName为空,这个时候就使用  local-ref
				// A reference to the id of another bean in the same XML file.
				refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);//将local-ref设置给  refName
				if (!StringUtils.hasLength(refName)) {
					// A reference to the id of another bean in a parent context.
					refName = ele.getAttribute(PARENT_REF_ATTRIBUTE); //如果localRef为null,这个时候需要将  parenet值设置为 refName.同时将
					toParent = true;
					if (!StringUtils.hasLength(refName)) {
						error("'bean', 'local' or 'parent' is required for <ref> element", ele);
						return null;
					}
				}
			}
			if (!StringUtils.hasText(refName)) {
				error("<ref> element contains empty target attribute", ele);
				return null;
			}
			RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);//根据获取到的ref信息来构造一下RuntimeReference。
			ref.setSource(extractSource(ele));
			return ref;
		}
		else if (nodeNameEquals(ele, IDREF_ELEMENT)) {//idRef解析,idRef主要用来注入一个bean的Id,注入的其实还是 一个 String的信息。
			return parseIdRefElement(ele);
		}
		else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
			return parseValueElement(ele, defaultValueType);
		}
		else if (nodeNameEquals(ele, NULL_ELEMENT)) {
			// It's a distinguished null value. Let's wrap it in a TypedStringValue
			// object in order to preserve the source location.
			TypedStringValue nullHolder = new TypedStringValue(null);
			nullHolder.setSource(extractSource(ele));
			return nullHolder;
		}
		else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
			return parseArrayElement(ele, bd);
		}
		else if (nodeNameEquals(ele, LIST_ELEMENT)) {
			return parseListElement(ele, bd);
		}
		else if (nodeNameEquals(ele, SET_ELEMENT)) {
			return parseSetElement(ele, bd);
		}
		else if (nodeNameEquals(ele, MAP_ELEMENT)) {
			return parseMapElement(ele, bd);
		}
		else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
			return parsePropsElement(ele);
		}
		else {
			error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
			return null;
		}
	}


看一下是如何解析 IdRef的Element的。其中返回的结果是一个RuntimeBeanNameReference的属性。
 

<! --   idref 主要通过  bean  和local两种方式来指定 -->
<idref bean="subClass"></idref>
<idref local="subClass"></idref>
public Object parseIdRefElement(Element ele) {
		// A generic reference to any name of any bean.
		String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);//获取到beanName。
		if (!StringUtils.hasLength(refName)) {//如果BeanName为空
			// A reference to the id of another bean in the same XML file.
			refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);//获取到localRef的信息
			if (!StringUtils.hasLength(refName)) {
				error("Either 'bean' or 'local' is required for <idref> element", ele);
				return null;
			}
		}
		if (!StringUtils.hasText(refName)) {   //如果这两种方式都没有对应的ref的信息,这个时候就报错。
			error("<idref> element contains empty target attribute", ele);
			return null;
		}
		RuntimeBeanNameReference ref = new RuntimeBeanNameReference(refName);
		ref.setSource(extractSource(ele));
		return ref;
	}

看一下  Value值是如何进行处理的:    返回的结果是一个  TypeStringValue

使用value值是这样设置的:

<property name="beanName" >
   <value type="java.lang.String">zhagnsan</value>
</property>

看下代码的实现:

/**
	 * Return a typed String value Object for the given value element.
	 */
	public Object parseValueElement(Element ele, String defaultTypeName) {
		// It's a literal value.
		String value = DomUtils.getTextValue(ele);//获取到其中的值
		String specifiedTypeName = ele.getAttribute(TYPE_ATTRIBUTE);//获取value对应的属性Type		String typeName = specifiedTypeName;
		if (!StringUtils.hasText(typeName)) {
			typeName = defaultTypeName;//设置默认的  typeName。
		}
		try {
			TypedStringValue typedValue = buildTypedStringValue(value, typeName);//构造  TypeStringValue的值,这个过程主要是将当前的对象添加到系统中。
			typedValue.setSource(extractSource(ele));
			typedValue.setSpecifiedTypeName(specifiedTypeName);
			return typedValue;
		}
		catch (ClassNotFoundException ex) {
			error("Type class [" + typeName + "] not found for <value> element", ele, ex);
			return value;
		}
	}

看一下是如何设置 Array 的属性值的:这个array是一个数组。

<property name="reds">
            <array value-type="java.lang.Integer">
                <value>12</value>
                <value>23</value>
                <value>33</value>
            </array>
</property>

看一下解析的代码,解析后返回一个ManagedArray对象。

public Object parseArrayElement(Element arrayEle, BeanDefinition bd) {
		String elementType = arrayEle.getAttribute(VALUE_TYPE_ATTRIBUTE);//获取value-type的属性。
		NodeList nl = arrayEle.getChildNodes();//获取所有的属性
		ManagedArray target = new ManagedArray(elementType, nl.getLength());//创建一个MannagedArray
		target.setSource(extractSource(arrayEle));//设置source。
		target.setElementTypeName(elementType);//设置一下elementType的值
		target.setMergeEnabled(parseMergeAttribute(arrayEle));//设置一下当前对象中的 是否能够进行merge。
		parseCollectionElements(nl, target, bd, elementType);//其中对当中的一个nodeList进行解析,这个过程主要是一个循环的解析 sub Element。
		return target;
	}

List的解析和Array的解析相类似。

Set的解析也想类似,主要是是 返回的结果中的ManagedSet中继承的是一个HashSet,而List中依赖的是一个List。

看下Map的解析过程,返回的结果是一个ManageMap的实现。

<property name="map">
    <map key-type="java.lang.String" value-type="java.lang.String">
         <entry key="lisi">
              <value>lisi</value>
         </entry>
         <entry key="wangwu">
               <value>wangwu</value>
         </entry>
     </map>
</property>
/**
	 * Parse a map element.
	 */
	public Map<Object, Object> parseMapElement(Element mapEle, BeanDefinition bd) {
		String defaultKeyType = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE);// 关键的key的类型值
		String defaultValueType = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE);// value 的类型值

		List<Element> entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT);//获取到所有的Entry中的值
		ManagedMap<Object, Object> map = new ManagedMap<Object, Object>(entryEles.size());//创建一个MangedMap的值
		map.setSource(extractSource(mapEle));//设置 source
		map.setKeyTypeName(defaultKeyType);//设置  keyType的值
		map.setValueTypeName(defaultValueType);//设置value的Type值
		map.setMergeEnabled(parseMergeAttribute(mapEle));//解析元素的合并元素

		for (Element entryEle : entryEles) {//对当前的EntryElement进行分别的解析。
			// Should only have one value child element: ref, value, list, etc.
			// Optionally, there might be a key child element.
			NodeList entrySubNodes = entryEle.getChildNodes();//获取到NodeList。其中每一个Node代表的是一个entry。
			Element keyEle = null;  //key值
			Element valueEle = null;//value值
			for (int j = 0; j < entrySubNodes.getLength(); j++) {
				Node node = entrySubNodes.item(j);
				if (node instanceof Element) {
					Element candidateEle = (Element) node;
					if (nodeNameEquals(candidateEle, KEY_ELEMENT)) {
						if (keyEle != null) {
							error("<entry> element is only allowed to contain one <key> sub-element", entryEle);
						}
						else {
							keyEle = candidateEle;
						}
					}
					else {
						// Child element is what we're looking for.
						if (nodeNameEquals(candidateEle, DESCRIPTION_ELEMENT)) {
							// the element is a <description> -> ignore it
						}
						else if (valueEle != null) {
							error("<entry> element must not contain more than one value sub-element", entryEle);
						}
						else {
							valueEle = candidateEle;
						}
					}
				}
			}

			// Extract key from attribute or sub-element.
			//提取Key值:key值有三种情况,第一种是  TypedStringValue。第二种是 RuntimeBeanReference。第三种可能是一个subElement对应的对象。
			Object key = null;
			boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE);//查看下当前的实现是否包含了 key值
			boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE);//看下是否包含了keyref
			if ((hasKeyAttribute && hasKeyRefAttribute) ||
					((hasKeyAttribute || hasKeyRefAttribute)) && keyEle != null) {//key的值不能为同时为空
				error("<entry> element is only allowed to contain either " +
						"a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle);
			}
			if (hasKeyAttribute) {//如果key值不为空,这个时候,key为一个 TypeStringValue的值。
				key = buildTypedStringValueForMap(entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyType, entryEle);
			}
			else if (hasKeyRefAttribute) {//如果keyRefAttribute不为null,这个时候需要完成的工作是创建一个RuntimeBeanReference的对象。
				String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE);
				if (!StringUtils.hasText(refName)) {
					error("<entry> element contains empty 'key-ref' attribute", entryEle);
				}
				RuntimeBeanReference ref = new RuntimeBeanReference(refName);
				ref.setSource(extractSource(entryEle));
				key = ref;
			}
			else if (keyEle != null) {
				key = parseKeyElement(keyEle, bd, defaultKeyType);//获取到key的value值。
			}
			else {
				error("<entry> element must specify a key", entryEle);
			}

			// 从Value提取对应的值。其中关键的是
			Object value = null;
			boolean hasValueAttribute = entryEle.hasAttribute(VALUE_ATTRIBUTE);
			boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE);
			boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE);
			if ((hasValueAttribute && hasValueRefAttribute) ||
					((hasValueAttribute || hasValueRefAttribute)) && valueEle != null) {
				error("<entry> element is only allowed to contain either " +
						"'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle);
			}
			if ((hasValueTypeAttribute && hasValueRefAttribute) ||
				(hasValueTypeAttribute && !hasValueAttribute) ||
					(hasValueTypeAttribute && valueEle != null)) {
				error("<entry> element is only allowed to contain a 'value-type' " +
						"attribute when it has a 'value' attribute", entryEle);
			}
			if (hasValueAttribute) {
				String valueType = entryEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
				if (!StringUtils.hasText(valueType)) {
					valueType = defaultValueType;
				}
				value = buildTypedStringValueForMap(entryEle.getAttribute(VALUE_ATTRIBUTE), valueType, entryEle);
			}
			else if (hasValueRefAttribute) {
				String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE);
				if (!StringUtils.hasText(refName)) {
					error("<entry> element contains empty 'value-ref' attribute", entryEle);
				}
				RuntimeBeanReference ref = new RuntimeBeanReference(refName);
				ref.setSource(extractSource(entryEle));
				value = ref;
			}
			else if (valueEle != null) {
				value = parsePropertySubElement(valueEle, bd, defaultValueType);
			}
			else {
				error("<entry> element must specify a value", entryEle);
			}

			// Add final key and value to the Map.
			map.put(key, value);//将结果添加到一个 ManagedMap<Object,Object>当中去。
		}

		return map;
	}

Map解析起来比较的复杂,主要是map中的key和value都可能是 value,ref,其他的subElement。这三种定义返回的结果都不一样,分别返回TypeStringValue,RuntimeBeanRegerence以及调用parseSubElement返回的结果。

下面看下 解析Qualifier 当中的属性元素:
Qualifier:主要解决的问题是按照类型进行注入的时候,当同一个类型找到了多个bean的时候,这个时候会发生歧义,会报错。这个时候使用Qualifer来指定其中一个值。解析结果是一个AutowireCandidateQualifier对象:

 <bean id="helloBean" class="com.test.bean.construct.HelloBean">
    <qualifier type="" value=""/>
</bean>
public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) {
		NodeList nl = beanEle.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
				parseQualifierElement((Element) node, bd);//解析 Qualifier的实现。
			}
		}
	}
public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
		String typeName = ele.getAttribute(TYPE_ATTRIBUTE); //注入的Type类型的名称、
		if (!StringUtils.hasLength(typeName)) {//如果类型名称为空,这个时候就报错。
			error("Tag 'qualifier' must have a 'type' attribute", ele);
			return;
		}
		this.parseState.push(new QualifierEntry(typeName));
		try {
			AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);//创建一个AutowireCandidateQualifier对象其中有了所有的待注入的内容对象的类型。
			qualifier.setSource(extractSource(ele));//设置source的值
			String value = ele.getAttribute(VALUE_ATTRIBUTE);//找到对应的value值
			if (StringUtils.hasLength(value)) {//如果确实设置了value值
				qualifier.setAttribute(AutowireCandidateQualifier.VALUE_KEY, value);
			}
			NodeList nl = ele.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {//在设置底层的对象。
				Node node = nl.item(i);
				if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
					Element attributeEle = (Element) node;
					String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE);
					String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE);
					if (StringUtils.hasLength(attributeName) && StringUtils.hasLength(attributeValue)) {
						BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
						attribute.setSource(extractSource(attributeEle));
						qualifier.addMetadataAttribute(attribute);
					}
					else {
						error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
						return;
					}
				}
			}
			bd.addQualifier(qualifier);
		}
		finally {
			this.parseState.pop();
		}
	}

以上为解析<bean>为一个GenericBeanDefinition的关键步骤。

4.6.1.4如果当前的beanName为空,就为这个对象生成一个默认的beanName。

生成默认的BeanName的算法 看下:
首先使用生成的Bean的Class的name。然后如果为空,就使用 parenetName+"$child"。接着还为空,就使用 factoryBeanName+"$created".最后还是为空,这个时候就报错。
然后需要处理一下重复的内容,如果是innerClass,这个时候,需要完成的功能是 id = id+"#"+hashCode. 如果这个对象当中已经有了额外的对象。这个时候可以使用  id= id+counter

看下代码:

public static String generateBeanName(
			BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
			throws BeanDefinitionStoreException {

		String generatedBeanName = definition.getBeanClassName();//获取到当期那bean对应的ClassName
		if (generatedBeanName == null) {
			if (definition.getParentName() != null) {
				generatedBeanName = definition.getParentName() + "$child";// parenetName+"$child".
			}
			else if (definition.getFactoryBeanName() != null) {
				generatedBeanName = definition.getFactoryBeanName() + "$created";//factroyBeanName+"$created".
			}
		}
		if (!StringUtils.hasText(generatedBeanName)) {//如果这三个还是为空,那么久报错
			throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
					"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
		}

		String id = generatedBeanName;
		if (isInnerBean) {//如果当前的class是一个innerBean,这个时候,需要完成的是 generateBeanName +"#"+当前Bean对应的Hashcode的唯一值。
			// Inner bean: generate identity hashcode suffix.
			id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
		}
		else {
			// Top-level bean: use plain class name.
			// Increase counter until the id is unique.
			int counter = -1;
			while (counter == -1 || registry.containsBeanDefinition(id)) {//如果当前的beanRegistry中如果包括了对应BeanName了。这个时候需要不断的对当前counter进行自增。
				counter++;
				id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
			}
		}
		return id;
	}

4.6.1.5 构造BeanDefinitionHolder

将GenericBeanDefinition和beanName和aliasName一起构造一个BeanDefinitionHolder对象。

 

 

4.6.2 扩展当前BeanDefinitionHolder
BeanDefinitionHolder decorateBeanDefinitionIfRequired(
            Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd)
            这个当中完成的功能,主要是用户在Element中自定义了attribute和子childNode:

public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
			Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {

		BeanDefinitionHolder finalDefinition = definitionHolder;//这个是解析完成的BeanDefinitionHolder。

		// Decorate based on custom attributes first.这个主要是用户在Element中定义的 attribute的信息。
		NamedNodeMap attributes = ele.getAttributes();//获取到所有的attribute。
		for (int i = 0; i < attributes.getLength(); i++) {
			Node node = attributes.item(i);
			finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);//如果其中有用户自定义的一些命名空间的内容,这个时候需要额外的调用对应NameSpaceHandlerResolver对象来对当前的对象进行额外的操作。
		}

		// Decorate based on custom nested elements.这个表示在当前Element中定义的  childNode信息。这些childNode是用户自定义相关的内容。
		NodeList children = ele.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node node = children.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
			}
		}
		return finalDefinition;
	}

4.6.3 注册BeanDefinition到BeanDefintionRegistry

将构造好的一个Bean写到BeanDefinitionRegistry中去:
调用了一个util方法:BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
看一下这个方法是如何实现的:

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();//获取到对应的beanName。
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //这个方法是将当前生成的GenericBeanDefinition。

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);//将别名注册到BeanDefinitionRegistry中去。
			}
		}
	}

看下在DefaultListableBeanFactory是如何注册的这个看下:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)//beanName  和  beanDefinition
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {//如果这个对象是AbstractBeanDefinition的实例。需要进行验证一下
			try {
				((AbstractBeanDefinition) beanDefinition).validate();//如果bean中有BeanClass对象,同时,Bean中有 OverrideMethod的时候,这个时候需要测试一下。
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition oldBeanDefinition;

		oldBeanDefinition = this.beanDefinitionMap.get(beanName);//获取到当前beanName在当前 Registry中已经存在的。
		if (oldBeanDefinition != null) {//如果 这个是替换
			if (!isAllowBeanDefinitionOverriding()) { //如果不允许替换,直接抛异常。
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
						"': There is already [" + oldBeanDefinition + "] bound.");
			}
			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {//判断一下不同的bean的role,这个时候需要打印一条提示日志。
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (this.logger.isWarnEnabled()) {
					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							oldBeanDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(oldBeanDefinition)) {//如果当前的bean和旧bean不相同的时候,这个时候就打印日志。
				if (this.logger.isInfoEnabled()) {
					this.logger.info("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);//将当前的bean添加到beanMap中去。		}
		else {
			if (hasBeanCreationStarted()) {//创建BeanMap是否开始了。这个时候判断一下当前的 alreadyCreated是否已经开始创建bean了
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {//对当前对象进行加锁
					this.beanDefinitionMap.put(beanName, beanDefinition);//将beanDefinition添加到Map中去。
					List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);//修改过的beanDefinitions的数量。
					updatedDefinitions.addAll(this.beanDefinitionNames);//将旧的beanDedinitions添加到updateDefinitions中去、
					updatedDefinitions.add(beanName);//然后将当前的beanName添加到 updateBeanDefinitions。
					this.beanDefinitionNames = updatedDefinitions;//这个时候使用 copyOfWrite来实现BeanDefinition的设置。
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);//如果有手动添加的单例Bean,这个时候需要将当前的bean删除掉。
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// 如果还没有开始创建,同时也不是覆盖
				this.beanDefinitionMap.put(beanName, beanDefinition);//将当前的bean添加到bean中去
				this.beanDefinitionNames.add(beanName);//beanDefinitionNames添加beanName
				this.manualSingletonNames.remove(beanName);//从手动单例Name中删除 beanName的信息。
			}
			this.frozenBeanDefinitionNames = null;
		}

		//如果就的BeanDefinition不为空,或者是singletonBean的队列中包含了当前的bean。这个时候需要对当前的bean进行重新加载。
		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

看下是如何复位BeanDefinition对象的:

protected void resetBeanDefinition(String beanName) {
		// Remove the merged bean definition for the given bean, if already created.
		clearMergedBeanDefinition(beanName);//首先将当前的beanName的bean对象从 mergedBeanDefinitionMap中移除

		// Remove corresponding bean from singleton cache, if any. Shouldn't usually
		// be necessary, rather just meant for overriding a context's default beans
		// (e.g. the default StaticMessageSource in a StaticApplicationContext).
		destroySingleton(beanName);//将当前的单例给删除掉

		// Reset all bean definitions that have the given bean as parent (recursively).
		//将所有的bean继承于当前的bean,都需要进行一下复位。
		for (String bdName : this.beanDefinitionNames) {
			if (!beanName.equals(bdName)) {
				BeanDefinition bd = this.beanDefinitionMap.get(bdName);
				if (beanName.equals(bd.getParentName())) {
					resetBeanDefinition(bdName);
				}
			}
		}
	}

 

转载于:https://my.oschina.net/u/3388174/blog/886543

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值