Spring配置文件的加载主要是在loadBeanDefinitoin方法中进行的
而这个方法又非常之复杂,我们本篇博客的目的就是详细讲解这一方法
this.loadBeanDefinitions(beanFactory);
点进去
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
this.loadBeanDefinitions(beanDefinitionReader);
}
第一行先是创建了一个Reader对象,将beanFactory进行了一个包装
第二行
beanDefinitionReader.setEnvironment(this.getEnvironment());
设置一些环境属性,用于xml文件中占位符以及其他符号的替换
第三行
beanDefinitionReader.setResourceLoader(this);
设置资源加载器
第四行
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
设置实体解析器
我们点进去看一下什么叫做实体解析器
public ResourceEntityResolver(ResourceLoader resourceLoader) {
super(resourceLoader.getClassLoader());
this.resourceLoader = resourceLoader;
}
点进super方法
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
this.dtdResolver = new BeansDtdResolver();
this.schemaResolver = new PluggableSchemaResolver(classLoader);
}
我们发现两个属性:dtdResolver和schemaResolver
它们分别是dtd文件的解析器和schema文件的解析器
点进new PluggableSchemaResolver(classLoader);中看看
public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
this.schemaMappingsLocation = "META-INF/spring.schemas";
}
我们看到了一个很熟悉的文件:“META-INF/spring.schemas”;
我们随意点进一个spring包的META-INF/spring.schemas中进行查看
http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-4.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-4.1.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-4.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans-4.3.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.2.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-4.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-4.1.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-4.2.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool-4.3.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-3.2.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-4.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-4.1.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-4.2.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util-4.3.xsd=org/springframework/beans/factory/xml/spring-util.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-4.0.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-4.1.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-4.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans-4.3.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
https\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-3.2.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-4.0.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-4.1.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-4.2.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool-4.3.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool.xsd
https\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-3.2.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-4.0.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-4.1.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-4.2.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util-4.3.xsd=org/springframework/beans/factory/xml/spring-util.xsd
https\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util.xsd
可以看到,它是将我们的一个网址路径对应到一个包路径,从而避免由于网络问题无法加载xml文件
而这个实体类解析器正是负责这一解析工作的
好了,下面就要详细介绍我们的loadBeanDefinition 对象了
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
getConfigLocations()看着是不是很眼熟?没错,我们在很早之前便进行过setConfiglocation的方法,这里是get
首先,将我们的每个xml文件都存入到configlocations这个String[]中
然后使用重载方法对其解析
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
String[] var3 = locations;
int var4 = locations.length;
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
count += this.loadBeanDefinitions(location);
}
return count;
}
}
里面对每个configlocation(即xml 文件进行了重载方法的解析)
点进去
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(location, (Set)null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
}
这个方法先是获取了ResourceLoader resourceLoader = this.getResourceLoader();
然后将String转换为location数组
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
它是如何转化的呢?点进去
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith("classpath*:")) {
return this.getPathMatcher().isPattern(locationPattern.substring("classpath*:".length())) ? this.findPathMatchingResources(locationPattern) : this.findAllClassPathResources(locationPattern.substring("classpath*:".length()));
} else {
int prefixEnd = locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 : locationPattern.indexOf(58) + 1;
return this.getPathMatcher().isPattern(locationPattern.substring(prefixEnd)) ? this.findPathMatchingResources(locationPattern) : new Resource[]{this.getResourceLoader().getResource(locationPattern)};
}
}
第一步的这个classpath就是我们在配置文件中经常使用的
<context:property-placeholder location="classpath:xxx.properties"/>
而我们的xml文件显然不会进入这一分支
所以我们会返回 new Resource[]{this.getResourceLoader().getResource(locationPattern)}
将我们的String对象封装成Resource对象
紧接着我们解析Resource对象
count = this.loadBeanDefinitions(resources);
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
Resource[] var3 = resources;
int var4 = resources.length;
for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
count += this.loadBeanDefinitions((Resource)resource);
}
return count;
}
这里我们对Resource数组的每个Resource 拿出来进行解析
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var6;
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
Throwable var4 = null;
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
var6 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} catch (Throwable var24) {
var4 = var24;
throw var24;
} finally {
if (inputStream != null) {
if (var4 != null) {
try {
inputStream.close();
} catch (Throwable var23) {
var4.addSuppressed(var23);
}
} else {
inputStream.close();
}
}
}
} catch (IOException var26) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var26);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var6;
}
}
注意 InputSource inputSource = new InputSource(inputStream);
我们已经开始往程序中输入一些文件内容了‘
var6 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
这个就是对其的解析
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
Document doc = this.doLoadDocument(inputSource, resource);
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}
我们可以看到,其将resource转换为document对象,然后将document对象中的内容注册到beanDefinition中,那么它具体是如何进行注册的呢
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
int countBefore = this.getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
点入这个注册bean定义的方法
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.doRegisterBeanDefinitions(doc.getDocumentElement());
}
进入里面的
this.doRegisterBeanDefinitions(doc.getDocumentElement());
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute("profile");
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
this.preProcessXml(root);
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}
这块就进入了核心处理的流程了’
刚开始先是创建了一个委派,即delegate,用来完成对节点的解析工作
下面判断profile属性直接跳过(在spring中一般不涉及这方面解析)
this.preProcessXml(root)和 this.postProcessXml(root)在spring中都为空,而在springmvc中会有相关扩展实现
我们重点看this.parseBeanDefinitions(root, this.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)) {
this.parseDefaultElement(ele, delegate);
} else {
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}
Element继承自node,而 root.getChildNodes()相当于获取所有子标签
接着开始遍历NodeList,如果是默认命名空间(如<bean>,<alias>),则使用parseDefaultElement(ele, delegate)进行解析,如果不是(如<aop:aspectj-autoproxy></aop:aspectj-autoproxy>),则使用delegate.parseCustomElement(root)
我们目前解析的是一个bean标签,所以会执行到第一种情况,我们点进去
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
我们处理的是bean,所以进入第三个分支
点进来
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
我们先是创建了一个BeanDefinitionHolder对象,BeanDefinitionHolder对象是BeanDefinition的封装类,封装了BeanDefinition,bean的名字和别名,我们可以用它完成IOC容器的注册
这个方法的整体流程是先解析,后注册
我们先看解析过程delegate.parseBeanDefinitionElement(ele);
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
this.checkNameUniqueness(beanName, aliases, ele);
}
AbstractBeanDefinition beanDefinition = this.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);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception var9) {
this.error(var9.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}
这个方法先获取Bean的id属性,然后获取name属性
如果有别名的话,将别名分割解析
然后看下面这个方法
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
这是与本方法同名的重载方法
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute("class")) {
className = ele.getAttribute("class").trim();
}
String parent = null;
if (ele.hasAttribute("parent")) {
parent = ele.getAttribute("parent");
}
try {
AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
this.parseMetaElements(ele, bd);
this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
this.parseConstructorArgElements(ele, bd);
this.parsePropertyElements(ele, bd);
this.parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(this.extractSource(ele));
AbstractBeanDefinition var7 = bd;
return var7;
} catch (ClassNotFoundException var13) {
this.error("Bean class [" + className + "] not found", ele, var13);
} catch (NoClassDefFoundError var14) {
this.error("Class that bean class [" + className + "] depends on not found", ele, var14);
} catch (Throwable var15) {
this.error("Unexpected failure during bean definition parsing", ele, var15);
} finally {
this.parseState.pop();
}
return null;
}
这个方法对bean元素进行详细的解析
先解析了class,parent,然后直接创建了beanDefinition对象,因为我们已经可以进行基本的反射操作了
AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
下面的一堆parse方法就是将我们bean标签中可能存在的元素统统进行了一个获取及解析
当我们将属性值统统解析完后,此时的beanDefinition 是一个完整的,解析完xml属性值的beanDefinition
。紧接着就包装我们之前提到过的holder对象
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
再次回到这个方法,下面就是对我们刚刚创建的beanDefinition对象注册,(以map形式,放入beanFaCTORY)以便以后使用