Spring框架进阶Spring V3.0 IOC源码分析流程
Posted 烟锁迷城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶Spring V3.0 IOC源码分析流程相关的知识,希望对你有一定的参考价值。
目录
1、总体分析
对于IOC的加载流程,可以在之前的IOC源码模仿中窥见一二。
总体步骤可以分为:
第一步,在ApplicationContext中,BeandefinitionReader用loadBeanDefinitions方法读取到配置文件的配置,保存到BeanDefinition之中,完成定位。
第二步,在ApplicationContext中获取到Beandefinition的列表,Beandefinition包含有Bean的名称和类信息,完成加载。
第三步,DefaultListableBeanFactory用doRegistryBeanDefinition方法将Beandefinition的列表放入BeanDefinitionMap中,完成注册
2、XML配置源码阅读
ApplicationContext是通常意义上的初始入口,从init方法内,直接调用ApplicationContext类,但实际上,因为配置方式的不同,所使用的ApplicationContext子类也并不相同。
2.1、XML配置
详细步骤可以分解为:
- 寻找入口
- 获取配置文件路径
- 开始启动
- 创建容器
- 载入配置路径
- 开始读取配置文件
- 分配解析策略
- 分配注册策略
- 向容器注册
2.1.1 寻找入口
ClassPathXmlApplicationContext是XML类型配置的子类,从构造中可以看到,它先是调用了父类的方法,然后setConfigLocations(configLocations)方法获取到了配置信息的地址,最后执行refresh()方法。
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException
super(parent);
setConfigLocations(configLocations);
if (refresh)
refresh();
2.1.2、获取配置文件路径
AbstractRefreshableConfigApplicationContext是setConfigLocations(configLocations)方法的来源,在这个方法里,将获取到的所有的配置地址都存方在一个String数组之中。
public void setConfigLocations(@Nullable String... locations)
if (locations != null)
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++)
// resolvePath为同一个类中将字符串解析为路径的方法
this.configLocations[i] = resolvePath(locations[i]).trim();
else
this.configLocations = null;
2.1.3、开始启动
AbstractApplicationContext之中包含了对应的refresh()方法,在这个方法内,可以看到第一个方法是准备刷新prepareRefresh(),第二个方法ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()是做什么的呢?
这里有一个熟悉的东西,ConfigurableListableBeanFactory,这个一定与DefaultListableBeanFactory有关,从方法名中猜测到,这个是要获取到刷新BeanFactory的一个方法,很显然,这个是为了得到一个BeanFactory,但具体是做什么的,还需要继续探究。
总体来说,refresh()方法主要负责整个IOC容器的刷新,包括构建和载入Bean的配置信息。如果IOC容器已经存在,就要被销毁,重新创建,是一个重启的过程。
public void refresh() throws BeansException, IllegalStateException
synchronized (this.startupShutdownMonitor)
// Prepare this context for refreshing.
//1、调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//2、告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
//子类的refreshBeanFactory()方法启动
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//3、为BeanFactory配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try
// Allows post-processing of the bean factory in context subclasses.
//4、为容器的某些子类指定特殊的BeanPost事件处理器
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//5、调用所有注册的BeanFactoryPostProcessor的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//6、为BeanFactory注册BeanPost事件处理器.
//BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//7、初始化信息源,和国际化相关.
initMessageSource();
// Initialize event multicaster for this context.
//8、初始化容器事件传播器.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//9、调用子类的某些特殊Bean初始化方法
onRefresh();
// Check for listener beans and register them.
//10、为事件传播器注册事件监听器.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//11、初始化所有剩余的单例Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//12、初始化容器的生命周期事件处理器,并发布容器的生命周期事件
finishRefresh();
catch (BeansException ex)
if (logger.isWarnEnabled())
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
// Destroy already created singletons to avoid dangling resources.
//13、销毁已创建的Bean
destroyBeans();
// Reset 'active' flag.
//14、取消refresh操作,重置容器的同步标识。
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
finally
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//15、重设公共缓存
resetCommonCaches();
2.1.4、创建容器
依然是AbstractApplicationContext之中的方法,第一个方法refreshBeanFactory(),刷新BeanFactory,第二个方法没什么好说的,就是将beanFactory拿到并返回,关键是第一个方法。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory()
//这里使用了委派设计模式,父类定义了抽象的refreshBeanFactory()方法,具体实现调用子类容器的refreshBeanFactory()方法
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled())
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
return beanFactory;
AbstractRefreshableApplicationContext,不同于之前的AbstractRefreshableConfigApplicationContext用来获取到配置文件的地址,AbstractRefreshableApplicationContext主要用来实现刷新功能,其为AbstractApplicationContext类的子类,使用委派模式,将refreshBeanFactory()方法的实现写在子类之中
refreshBeanFactory()方法的实现并不复杂,如果存在容器,就销毁Bean,并且关闭容器,然后开始创建。
创建自然是最重要的,因为我们看到了一个熟悉的东西,DefaultListableBeanFactory beanFactory = createBeanFactory(),这个我们太熟了,再看下面的方法,loadBeanDefinitions(beanFactory),这个也太熟悉了,先创建DefaultListableBeanFactor,再用loadBeanDefinitions(beanFactory)方法,获取到BeanDefinitionsList。
protected final void refreshBeanFactory() throws BeansException
//如果已经有容器,销毁容器中的bean,关闭容器
if (hasBeanFactory())
destroyBeans();
closeBeanFactory();
try
//创建IOC容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//对IOC容器进行定制化,如设置启动参数,开启注解的自动装配等
customizeBeanFactory(beanFactory);
//调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor)
this.beanFactory = beanFactory;
catch (IOException ex)
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
2.1.5、载入配置路径
AbstractXmlApplicationContext,依然是一个抽象类,是上一个AbstractRefreshableConfigApplicationContext的子类,是的这里再次使用委派模式,实现loadBeanDefinitions(beanFactory)方法
第一行,看到了一个很熟悉的东西,BeanDefinitionReader,配置文件读取,获取到对应的Reader之后,继续向下看,期间放入了各种配置,最后执行方法loadBeanDefinitions(beanDefinitionReader),显然这里才继续执行读取了
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容 器使用该读取器读取Bean定义资源
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
//为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的
//祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
//为Bean读取器设置SAX xml解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
initBeanDefinitionReader(beanDefinitionReader);
//Bean读取器真正实现加载的方法
loadBeanDefinitions(beanDefinitionReader);
依然是AbstractXmlApplicationContext类,将Reader读取到之后,获取资源,如果资源不为空,就执行Reader的loadBeanDefinitions(configResources)方法,可以看到,这里根据获取到的资源类型分为两个方法,一个以resource为参,一个以string为参
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException
//获取Bean定义资源的定位
Resource[] configResources = getConfigResources();
if (configResources != null)
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
//的Bean定义资源
reader.loadBeanDefinitions(configResources);
//如果子类中获取的Bean定义资源定位为空,则获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源
String[] configLocations = getConfigLocations();
if (configLocations != null)
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
//的Bean定义资源
reader.loadBeanDefinitions(configLocations);
AbstractBeanDefinitionReader类为XmlBeanDefinitionReader的父类,可以先看loadBeanDefinitions(String location)方法,这里是loadBeanDefinitions(String location, null)的重载方法,继续向下,可以看到重载方法中还有loadBeanDefinitions(resources)方法
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException
return loadBeanDefinitions(location, null);
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException
//获取在IoC容器初始化过程中设置的资源加载器
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
//将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源
//加载多个指定位置的Bean定义资源文件
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
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.
//将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源
//加载单个指定位置的Bean定义资源文件
Resource resource = resourceLoader.getResource(location);
//委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
int loadCount = loadBeanDefinitions(resource);
if (actualResources != null)
actualResources.add(resource);
if (logger.isDebugEnabled())
logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
return loadCount;
2.1.6、读取配置内容
这个方法是子类XmlBeanDefinitionReader的方法,依旧调用此类中的loadBeanDefinitions方法,最后可以看到doLoadBeanDefinitions方法,在源码中,带有do开头的方法就是真正的执行方法。
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException
//将读入的XML资源进行特殊编码处理
return loadBeanDefinitions(new EncodedResource(resource));
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<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
if (!currentResources.add(encodedResource))
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
try
//将资源文件转为InputStream的IO流
InputStream inputStream = encodedResource.getResource().getInputStream();
try
//从InputStream中得到XML的解析源
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null)
inputSource.setEncoding(encodedResource.getEncoding());
//这里是具体的读取过程
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
finally
//关闭从Resource中得到的IO流
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();
那么回去重新看以resource为参的方法
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException
//获取Bean定义资源的定位
Resource[] configResources = getConfigResources();
if (configResources != null)
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
//的Bean定义资源
reader.loadBeanDefinitions(configResources);
//如果子类中获取的Bean定义资源定位为空,则获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源
String[] configLocations = getConfigLocations();
if (configLocations != null)
//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
//的Bean定义资源
reader.loadBeanDefinitions(configLocations);
在这个方法中,依然有loadBeanDefinitions(resource)方法
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources)
counter += loadBeanDefinitions(resource);
return counter;
执行的依旧是XmlBeanDefinitionReader的方法,依旧调用此类中的loadBeanDefinitions方法,最后可以看到doLoadBeanDefinitions方法,由此可见,最后执行的是相同的方法。
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException
//将读入的XML资源进行特殊编码处理
return loadBeanDefinitions(new EncodedResource(resource));
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<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
if (!currentResources.add(encodedResource))
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
try
//将资源文件转为InputStream的IO流
InputStream inputStream = encodedResource.getResource().getInputStream();
try
//从InputStream中得到XML的解析源
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null)
inputSource.setEncoding(encodedResource.getEncoding());
//这里是具体的读取过程
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
finally
//关闭从Resource中得到的IO流
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();
2.1.7、分配解析策略
依旧是XmlBeanDefinitionReader类中的方法,可以看到这个方法registerBeanDefinitions(doc, resource),这也是一个很熟悉的方法,执行BeanDefinition的注册行为。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException
try
//将XML文件转换为DOM对象,解析过程由documentLoader实现
Document doc = doLoadDocument(inputSource, resource);
//这里是启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则
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);
XmlBeanDefinitionReader类的registerBeanDefinitions方法继续进行BeanDefinitions的注册,在这个过程中,进入到DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions之中
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException
//得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//获得容器中注册的Bean数量
int countBefore = getRegistry().getBeanDefinitionCount();
//解析过程入口,这里使用了委派模式,BeanDefinitionDocumentReader只是个接口,
//具体的解析实现过程有实现类DefaultBeanDefinitionDocumentReader完成
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//统计解析的Bean数量
return getRegistry().getBeanDefinitionCount() - countBefore;
DefaultBeanDefinitionDocumentReader类包含有doRegisterBeanDefinitions(root)方法,这个是真正执行注册的方法
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
//获得XML描述符
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
//获得Document的根元素
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
DefaultBeanDefinitionDocumentReader类包含有BeanDefinitionParserDelegate parent = this.delegate,这依旧是一个委派方法,用来执行对应的解析,那么跟着这个委派的类,继续向下找,找到parseBeanDefinitions(root, this.delegate)方法,这个方法就是继续执行的方法
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实现,
//BeanDefinitionParserDelegate中定义了Spring Bean定义XML文件的各种元素
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);
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;
//在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性
preProcessXml(root);
//从Document的根元素开始进行Bean定义的Document对象
parseBeanDefinitions(root, this.delegate);
//在解析Bean定义之后,进行自定义的解析,增加解析过程的可扩展性
postProcessXml(root);
this.delegate = parent;
DefaultBeanDefinitionDocumentReader类的parseDefaultElement(ele, delegate)方法解析Bean标签,继续向下
//使用Spring的Bean规则从Document的根元素开始进行Bean定义的Document对象
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)
//Bean定义的Document对象使用了Spring默认的XML命名空间
if (delegate.isDefaultNamespace(root))
//获取Bean定义的Document对象根元素的所有子节点
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++)
Node node = nl.item(i);
//获得Document节点是XML元素节点
if (node instanceof Element)
Element ele = (Element) node;
//Bean定义的Document的元素节点使用的是Spring默认的XML命名空间
if (delegate.isDefaultNamespace(ele))
//使用Spring的Bean规则解析元素节点
parseDefaultElement(ele, delegate);
else
//没有使用Spring默认的XML命名空间,则使用用户自定义的解//析规则解析元素节点
delegate.parseCustomElement(ele);
else
//Document的根节点没有使用Spring默认的命名空间,则使用用户自定义的
//解析规则解析Document根节点
delegate.parseCustomElement(root);
DefaultBeanDefinitionDocumentReader类的processBeanDefinition(ele, delegate),继续解析Bean标签,继续向下
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)
//如果元素节点是<Import>导入元素,进行导入解析
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT))
importBeanDefinitionResource(ele);
//如果元素节点是<Alias>别名元素,进行别名解析
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT))
processAliasRegistration(ele);
//元素节点既不是导入元素,也不是别名元素,即普通的<Bean>元素,
//按照Spring的Bean规则解析元素
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT))
processBeanDefinition(ele, delegate);
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT))
// recurse
doRegisterBeanDefinitions(ele);
DefaultBeanDefinitionDocumentReader类的BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法,调用BeanDefinitionReaderUtils工具类去注册BeanDefinitions。
除此之外,第一行代码BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele)也相当重要,这个方法展示了在BeanDefinition是如何封装的。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
// BeanDefinitionHolder是对BeanDefinition的封装,即Bean定义的封装类
//对Document对象中<Bean>元素的解析由BeanDefinitionParserDelegate实现
// BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null)
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try
// Register the final decorated instance.
//向Spring IOC容器注册解析得到的Bean定义,这是Bean定义向IOC容器注册的入口
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
catch (BeanDefinitionStoreException ex)
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
// Send registration event.
//在完成向Spring IOC容器注册解析得到的Bean定义之后,发送注册事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
BeanDefinitionParserDelegate类中的方法parseBeanDefinitionElement内的AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean)继续对BeanDefinition进行构建,
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele)
return parseBeanDefinitionElement(ele, null);
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean)
//获取<Bean>元素中的id属性值
String id = ele.getAttribute(ID_ATTRIBUTE);
//获取<Bean>元素中的name属性值
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//获取<Bean>元素中的alias属性值
List<String> aliases = new ArrayList<>();
//将<Bean>元素中的所有name属性值存放到别名中
if (StringUtils.hasLength(nameAttr))
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
String beanName = id;
//如果<Bean>元素中没有配置id属性时,将别名中的第一个值赋值给beanName
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");
//检查<Bean>元素所配置的id或者name的唯一性,containingBean标识<Bean>
//元素中是否包含子<Bean>元素
if (containingBean == null)
//检查<Bean>元素所配置的id、name或者别名是否重复
checkNameUniqueness(beanName, aliases, ele);
//详细对<Bean>元素中配置的Bean定义进行解析的地方
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null)
if (!StringUtils.hasText(beanName))
try
if (containingBean != null)
//如果<Bean>元素中没有配置id、别名或者name,且没有包含子元素
//<Bean>元素,为解析的Bean生成一个唯一beanName并注册
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
else
//如果<Bean>元素中没有配置id、别名或者name,且包含了子元素
//<Bean>元素,为解析的Bean使用别名向IOC容器注册
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.
//为解析的Bean使用别名注册时,为了向后兼容
//Spring1.2/2.0,给别名添加类名后缀
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);
//当解析出错时,返回null
return null;
BeanDefinitionParserDelegate类中的方法parseBeanDefinitionElement保存了BeanDefinition中需要的一些属性和内容,大致完成了构建。
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean)
//记录解析的<Bean>
this.parseState.push(new BeanEntry(beanName));
//这里只读取<Bean>元素中配置的class名字,然后载入到BeanDefinition中去
//只是记录配置的class名字,不做实例化,对象的实例化在依赖注入时完成
String className = null;
//如果<Bean>元素中配置了parent属性,则获取parent属性的值
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
//根据<Bean>元素配置的class名称和parent属性值创建BeanDefinition
//为载入Bean定义信息做准备
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//对当前的<Bean>元素中配置的一些属性进行解析和设置,如配置的单态(singleton)属性等
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//为<Bean>元素解析的Bean设置description信息
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//对<Bean>元素的meta(元信息)属性解析
parseMetaElements(ele, bd);
//对<Bean>元素的lookup-method属性解析
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//对<Bean>元素的replaced-method属性解析
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//解析<Bean>元素的构造方法设置
parseConstructorArgElements(ele, bd);
//解析<Bean>元素的<property>设置
parsePropertyElements(ele, bd);
//解析<Bean>元素的qualifier属性
parseQualifierElements(ele, bd);
//为当前解析的Bean设置所需的资源和依赖对象
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();
//解析<Bean>元素出错时,返回null
return null;
2.1.8、分配注册策略
BeanDefinitionReaderUtils工具类中,执行registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())方法
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException
// Register bean definition under primary name.
//获取解析的BeanDefinition的名称
String beanName = definitionHolder.getBeanName();
//向IOC容器注册BeanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
//如果解析的BeanDefinition有别名,向容器为其注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null)
for (String alias : aliases)
registry.registerAlias(beanName, alias);
2.1.9、向容器注册
最后,来到DefaultListableBeanFactory类,最终这里,我们终于看到了想要看的东西:
this.beanDefinitionMap.put(beanName, beanDefinition);
这个beanDefinitionMap就是
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
专用来保存注册信息的BeanDefinition
这显然符合最开始的IOC设计,ApplicationContext持有DefaultListableBeanFactory的引用,两者都继承了BeanFactory,是静态代理模式。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
//校验解析的BeanDefiniton
if (beanDefinition instanceof AbstractBeanDefinition)
try
((AbstractBeanDefinition) beanDefinition).validate();
catch (BeanDefinitionValidationException ex)
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
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())
// 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))
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);
else
if (hasBeanCreationStarted())
// Cannot modify startup-time collection elements anymore (for stable iteration)
//注册的过程中需要线程同步,以保证数据的一致性
synchronized (this.beanDefinitionMap)
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName))
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
else
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
//检查是否有同名的BeanDefinition已经在IOC容器中注册
if (oldBeanDefinition != null || containsSingleton(beanName))
//重置所有已经注册过的BeanDefinition的缓存
resetBeanDefinition(beanName);
2.2、XML方式总结
以下流程总结包含类和方法,流程顺序为类中调用某一方法至另一类中
2.2.1、保存配置文件路径
ClassPathXmlApplicationContext:起始ApplicationContext,根据构造方法,执行setConfigLocations去获取文件路径并保存
setConfigLocations:保存至对应String数组
AbstractRefreshableApplicationContext:具体执行位置
2.2.2、定位配置文件
ClassPathXmlApplicationContext:起始ApplicationContext,根据构造方法,执行refresh
refresh:容器的刷新功能,如果不存在容器,就创建一个容器,如果已经存在,就注销Bean,销毁容器,重新建立
AbstractApplicationContext:ClassPathXmlApplicationContext父类
obtainFreshBeanFactory:告诉子类开始执行refreshBeanFactory方法
AbstractApplicationContext:ClassPathXmlApplicationContext父类
refreshBeanFactory:如果已有容器,销毁,创建IOC容器DefaultListableBeanDefinition,执行loadBeanDefinitions方法,开始准备读取
AbstractRefreshableApplicationContext:
loadBeanDefinitions:创建Bean读取器XmlBeanDefinitionReader,继续执行读取
2.2.3、加载配置文件信息
AbstractXmlApplicationContext:
loadBeanDefinitions:资源定位,分为两种方式,Resource参数和String参数两种
AbstractBeanDefinitionReader:
loadBeanDefinitions:两种方式最终都将到达XmlBeanDefinitionReader
XmlBeanDefinitionReader:
doLoadBeanDefinitions:真正执行读取的方法,
XmlBeanDefinitionReader:
registerBeanDefinitions:执行注册方法
2.2.4、注册BeanDefinition至Map
DefaultBeanDefinitionDocumentReader:默认BeanDefinition文档读取器,执行读取
doRegisterBeanDefinitions:执行BeanDefinition的注册流程
DefaultBeanDefinitionDocumentReader:继续执行读取
processBeanDefinition:根据委派的BeanDefinitionParserDelegate解析配置文件,装载BeanDefinition类信息并封装到BeanDefinitionHolder中
获取到封装BeanDefinition的BeanDefinitionHolder,并执行下一步的保存
BeanDefinitionReaderUtils:将解析的BeanDefinitionHold注册到容器中
registerBeanDefinition:获取到BeanDefinition用来执行最后的保存
DefaultListableBeanFactory:最终保存BeanDefinition的类,保存到beanDefinitionMap
3、注解方式阅读源码
注解方式和XML方式略有不同
3.1、起始入口
AnnotationConfigApplicationContext是注解的起始类,包含一个读取器AnnotatedBeanDefinitionReader和扫描器ClassPathBeanDefinitionScanner,在默认的无参构造中将读取器和扫描器会被初始化,并且在有参构造中都调用了无参构造。
在两个带有参数的构造器中可以看到,这是两种不同的扫描方式,一种是使用配置类,一种是使用给定包路径扫描
/保存一个读取注解的Bean定义读取器,并将其设置到容器中
private final AnnotatedBeanDefinitionReader reader;
//保存一个扫描指定类路径中注解Bean定义的扫描器,并将其设置到容器中
private final ClassPathBeanDefinitionScanner scanner;
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through @link #register calls and then manually @linkplain #refresh refreshed.
*/
//默认构造函数,初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其register()
//方法注册配置类,并调用refresh()方法刷新容器,触发容器对注解Bean的载入、解析和注册过程
public AnnotationConfigApplicationContext()
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. @link Configuration @Configuration classes
*/
//最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的Bean自动注册到容器中
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses)
this();
register(annotatedClasses);
refresh();
/**
* Create a new AnnotationConfigApplicationContext, scanning for bean definitions
* in the given packages and automatically refreshing the context.
* @param basePackages the packages to check for annotated classes
*/
//该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的Spring Bean,将其注册到容器中
public AnnotationConfigApplicationContext(String... basePackages)
this();
scan(basePackages);
refresh();
3.2、类参数构造执行
在执行熟悉的refresh方法之前,会先执行ApplicationContext中的register,进而执行AnnotatedBeanDefinitionReader中的register,最后执行doRegister。
在doRegister方法中,关键的步骤有几个:
- ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd),获取到Bean的作用域,是原型还是单例
- AnnotationConfigUtils.processCommonDefinitionAnnotations(abd),处理Bean上的其他注解
- definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry),完成BeanDefinitionHolder的构建,类似于XML方式,但在此处,将根据作用域参数决定对应的代理策略
- BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry),注册BeanDefinition信息。
public void register(Class<?>... annotatedClasses)
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
public void register(Class<?>... annotatedClasses)
for (Class<?> annotatedClass : annotatedClasses)
registerBean(annotatedClass);
public void registerBean(Class<?> annotatedClass)
doRegisterBean(annotatedClass, null, null, null);
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers)
//根据指定的注解Bean定义类,创建Spring容器中对注解Bean的封装的数据结构
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata()))
return;
abd.setInstanceSupplier(instanceSupplier);
//解析注解Bean定义的作用域,若@Scope("prototype"),则Bean为原型类型;
//若@Scope("singleton"),则Bean为单态类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//为注解Bean定义设置作用域
abd.setScope(scopeMetadata.getScopeName());
//为注解Bean定义生成Bean名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理注解Bean定义中的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//如果在向容器注册注解Bean定义时,使用了额外的限定符注解,则解析限定符注解。
//主要是配置的关于autowiring自动依赖注入装配的限定条件,即@Qualifier注解
//Spring自动依赖注入装配默认是按类型装配,如果使用@Qualifier则按名称
if (qualifiers != null)
for (Class<? extends Annotation> qualifier : qualifiers)
//如果配置了@Primary注解,设置该Bean为autowiring自动依赖注入装//配时的首选
if (Primary.class == qualifier)
abd.setPrimary(true);
//如果配置了@Lazy注解,则设置该Bean为非延迟初始化,如果没有配置,
//则该Bean为预实例化
else if (Lazy.class == qualifier)
abd.setLazyInit(true);
//如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一
//个autowiring自动依赖注入装配限定符,该Bean在进autowiring
//自动依赖注入装配时,根据名称装配限定符指定的Bean
else
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
for (BeanDefinitionCustomizer customizer : definitionCustomizers)
customizer.customize(abd);
//创建一个指定Bean名称的Bean定义对象,封装注解Bean定义类数据
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//根据注解Bean定义类中配置的作用域,创建相应的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//向IOC容器注册注解Bean类定义对象
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
3.2.1、作用域解析
AnnotationScopeMetadataResolver类
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType)方法将注解和注解值放入一个Map之中,AnnotationAttributes继承了LinkHashMap。
如果注解数值不为空,就可以将获取到的作用域值放入metadata,这个值在attributes.getEnum("proxyMode")之中获取到
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition)
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition)
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
//从注解Bean定义类的属性中查找属性为”Scope”的值,即@Scope注解的值
//annDef.getMetadata().getAnnotationAttributes()方法将Bean
//中所有的注解和注解的值存放在一个map集合中
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
//将获取到的@Scope注解的值设置到要返回的对象中
if (attributes != null)
metadata.setScopeName(attributes.getString("value"));
//获取@Scope注解中的proxyMode属性值,在创建代理对象时会用到
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
//如果@Scope的proxyMode属性为DEFAULT或者NO
if (proxyMode == ScopedProxyMode.DEFAULT)
//设置proxyMode为NO
proxyMode = this.defaultProxyMode;
//为返回的元数据设置proxyMode
metadata.setScopedProxyMode(proxyMode);
//返回解析的作用域元信息对象
return metadata;
3.2.2、通用注解处理
AnnotationConfigUtils类
在这里对懒加载,首选项,名称加载等注解进行对应处理
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata)
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
//如果Bean定义中有@Lazy注解,则将该Bean预实例化属性设置为@lazy注解的值
if (lazy != null)
abd.setLazyInit(lazy.getBoolean("value"));
else if (abd.getMetadata() != metadata)
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null)
abd.setLazyInit(lazy.getBoolean("value"));
//如果Bean定义中有@Primary注解,则为该Bean设置为autowiring自动依赖注入装配的首选对象
if (metadata.isAnnotated(Primary.class.getName()))
abd.setPrimary(true);
//如果Bean定义中有@ DependsOn注解,则为该Bean设置所依赖的Bean名称,
//容器将确保在实例化该Bean之前首先实例化所依赖的Bean
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null)
abd.setDependsOn(dependsOn.getStringArray("value"));
if (abd instanceof AbstractBeanDefinition)
AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null)
absBd.setRole(role.getNumber("value").intValue());
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null)
absBd.setDescription(description.getString("value"));
3.2.3、代理模式选择
AnnotationConfigUtils类
在这里根据作用域值的不同,对BeanDefinitionHolder做不同的处理
如果为ScopedProxyMode.NO就不做代理
如果为ScopedProxyMode.TARGET_CLASS,就为true
如果为ScopedProxyMode.INTERFACES,就为false
分别执行不同的策略
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry)
//获取注解Bean定义类中@Scope注解的proxyMode属性值
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
//如果配置的@Scope注解的proxyMode属性值为NO,则不应用代理模式
if (scopedProxyMode.equals(ScopedProxyMode.NO))
return definition;
//获取配置的@Scope注解的proxyMode属性值,如果为TARGET_CLASS
//则返回true,如果为INTERFACES,则返回false
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
//为注册的Bean创建相应模式的代理对象
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
3.2.4、注册BeanDefinition
BeanDefinitionReaderUtils类,向IOC进行注册的方法:registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()),这个方法就是向DefaultListableBeanFactory中进行注册。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException
// Register bean definition under primary name.
//获取解析的BeanDefinition的名称
String beanName = definitionHolder.getBeanName();
//向IOC容器注册BeanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
//如果解析的BeanDefinition有别名,向容器为以上是关于Spring框架进阶Spring V3.0 IOC源码分析流程的主要内容,如果未能解决你的问题,请参考以下文章