书接前文:Spring5源码之二——refresh方法之prepareRefresh(),接下来,我们详细了解一下obtainFreshBeanFactory()方法,这个方法核心做了两件事,一是创建BeanFactory并赋值该属性,二是将解析XML中bean配置构造BeanDefinitions。
/**
* 解析Spring配置文件,根据配置文件(如果解析到<context:component-scan base-package="" />或@Controller、@Service、@Component、@Repository等注解时,会解析对应Bean对象)解析bean信息封装成BeanDefinition对象,并更新BeanFactory中集合。
*
* 主要更新BeanFactory中的三个集合对象:
* beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。prepareRefresh
* beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射。
* aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
(1)obtainFreshBeanFactory()方法会调用自身类的方法
//告诉子类刷新内部 bean 工厂,返回新的BeanFactory实例
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//子类必须实现此方法才能执行实际的配置加载。 该方法在任何其他初始化工作之前由refresh()调用。子类将创建一个新的 bean 工厂并保存对它的引用,或者返回它保存的单个 BeanFactory 实例。
//在后一种情况下,如果多次刷新上下文,它通常会抛出 IllegalStateException。
refreshBeanFactory();
//抽象方法,由ConfigurableListableBeanFactory子类实现
return getBeanFactory();
}
(2)在(1)中的refreshBeanFactory()方法,调用类的refreshBeanFactory()方法。
//此实现执行此上下文的底层 bean 工厂的实际刷新,关闭先前的 bean 工厂(如果有)并为上下文生命周期的下一个阶段初始化一个新的 bean 工厂。
@Override
protected final void refreshBeanFactory() throws BeansException {
//判断BeanFactory是否存在,如果存在则先关闭,销毁已存在的BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//自定义此上下文使用的内部 bean 工厂。 为每次refresh()尝试调用。如果指定,默认实现应用此上下文的“allowBeanDefinitionOverriding”和“allowCircularReferences”设置。 可以在子类中覆盖以自定义DefaultListableBeanFactory的任何设置。
customizeBeanFactory(beanFactory);
//将 bean 定义加载到给定的 bean 工厂中,通常是通过委托给一个或多个 bean 定义读取器(默认:XmlBeanDefinitionReader),由AbstractXmlWebApplicationContext实现
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
(3)在(2)中的destroyBeans()方法,先调用AbstractRefreshableApplicationContext类获取BeanFactory。
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
//-------------------------------------------------------------------
//-------------AbstractRefreshableApplicationContext类---------------
//-------------------------------------------------------------------
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
@Nullable
private DefaultListableBeanFactory beanFactory;
//内部BeanFactory的同步监视器
private final Object beanFactoryMonitor = new Object();
//省略其他代码
//......
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
}
然后调用ConfigurableBeanFactory接口的destroySingletons()方法,最终由DefaultListableBeanFactory类实现。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//其他省略
//......
@Override
public void destroySingletons() {
super.destroySingletons();//调用到父类DefaultSingletonBeanRegistry
//更新工厂的内部手动单例名称集
updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
//删除有关按类型映射的任何假设
clearByTypeCache();
}
/**
* Remove any assumptions about by-type mappings.
*/
private void clearByTypeCache() {
//单例和非单例 bean 名称的映射,由依赖类型键入
this.allBeanNamesByType.clear();
//单例 bean 名称映射,由依赖类型键控
this.singletonBeanNamesByType.clear();
}
}
//------------------------------------------------------------
//-------------DefaultSingletonBeanRegistry类-----------------
//------------------------------------------------------------
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//其他省略
//......
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
//指示我们当前是否在destroySingletons中的标志
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
//调用下面destroySingleton(String beanName)方法
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();
}
//销毁给定的 bean。 如果找到相应的一次性 bean 实例,则委托给destroyBean
public void destroySingleton(String beanName) {
removeSingleton(beanName);
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);//调用下面摧毁bean方法
}
//
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
//摧毁包含的bean
Set<String> containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
//从其他的bean依赖中删除被摧毁的bean
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
//移除被摧毁bean的依赖准备信息
this.dependenciesForBeanMap.remove(beanName);
}
}
(4)在(2)中的closeBeanFactory()方法,调用AbstractRefreshableApplicationContext类的closeBeanFactory()方法。
@Override
//子类必须实现此方法以释放其内部 bean 工厂。 在所有其他关闭工作之后, close()会调用此方法。
永远不应该抛出异常,而是记录关闭失败
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory != null) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}
}
(5)在(2)中的createBeanFactory()方法,调用AbstractRefreshableApplicationContext类的createBeanFactory()方法,返回一个DefaultListableBeanFactory对象。
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
(6)在(2)中的customizeBeanFactory(beanFactory)方法,先调用自身的customizeBeanFactory(DefaultListableBeanFactory beanFactory)方法,
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//设置是否允许具有相同名称的Bean来覆盖之前的Bean
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//设置是否允许循环引用,默认是允许循环依赖的
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
(7)在(2)中的loadBeanDefinitions(beanFactory)方法,此方法是将XML解析为BeanDefinition的核心。
loadBeanDefinitions(beanFactory) 在AbstractRefreshableApplicationContext自身类是一个抽象方法,如下所示。
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
其主要实现以AbstractXmlApplicationContext子类实现为例。
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建一个XmlBeanDefinition读取器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//设置环境变量
beanDefinitionReader.setEnvironment(this.getEnvironment());
//设置资源加载器
beanDefinitionReader.setResourceLoader(this);
//设置实体解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//初始化用于加载此上下文的 bean 定义的 bean 定义读取器。 默认实现为空。
可以在子类中覆盖,例如关闭 XML 验证或使用不同的 XmlBeanDefinitionParser 实现
initBeanDefinitionReader(beanDefinitionReader);
//【核心+重点】根据xml配置,解析为BeanDefinition
loadBeanDefinitions(beanDefinitionReader);
}
new XmlBeanDefinitionReader(beanFactory)调用AbstractBeanDefinitionReader类的AbstractBeanDefinitionReader(BeanDefinitionRegistry registry)方法。
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
//设置资源加载器
if (this.registry instanceof ResourceLoader) {
this.resourceLoader = (ResourceLoader) this.registry;
}
else {
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
// 设置环境变量
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
}
else {
this.environment = new StandardEnvironment();
}
}
loadBeanDefinitions(XmlBeanDefinitionReader reader)方法,
//------------------------AbstractXmlApplicationContext类------------------------
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
//省略部分代码...
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//返回一个 Resource 对象数组,引用该上下文应该使用的 XML bean 定义文件。
默认实现返回null 。 子类可以覆盖它以提供预先构建的资源对象而不是位置字符串
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//返回一个资源位置数组,指的是构建此上下文时应使用的 XML bean 定义文件。 还可以包括位置模式,这将通过 ResourcePatternResolver 解决。默认实现返回null 。 子类可以覆盖它以提供一组资源位置来加载 bean 定义
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//bean读取器根据配置文件或注解将Bean转换成BeanDefinition对象
reader.loadBeanDefinitions(configLocations);
}
}
@Nullable
protected Resource[] getConfigResources() {
return null;
}
}
//---------------------------AbstractBeanDefinitionReader类----------------------
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
//调用
count += loadBeanDefinitions(resource);
}
return count;
}
}
//--------------------------XmlBeanDefinitionReader类------------------------
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
//省略部分代码......
//从指定的 XML 文件加载 bean 定义
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
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 inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//调用
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
//实际上从指定的 XML 文件加载 bean 定义
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//读取xml文件
Document doc = doLoadDocument(inputSource, resource);
//根据xml解析beandefinitions,并返回bean数量
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
//读取xml文件并加载
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
//根据读取的xml文件,加载为beandefinitions
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
//具体注册beandefinitions
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
}
而documentReader.registerBeanDefinitions(doc, createReaderContext(resource))最终调用DefaultBeanDefinitionDocumentReader类,对XML进行解析。
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
public static final String NESTED_BEANS_ELEMENT = "beans";
public static final String ALIAS_ELEMENT = "alias";
public static final String NAME_ATTRIBUTE = "name";
public static final String ALIAS_ATTRIBUTE = "alias";
public static final String IMPORT_ELEMENT = "import";
public static final String RESOURCE_ATTRIBUTE = "resource";
public static final String PROFILE_ATTRIBUTE = "profile";
//省略部分代码......
@Override
//此实现根据“spring-beans”XSD(或历史上的 DTD)解析 bean 定义。
打开一个 DOM 文档; 然后初始化在<beans/>级别指定的默认设置; 然后解析包含的 bean 定义
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
//在给定的根<beans/>元素中注册每个 bean 定义
doRegisterBeanDefinitions(doc.getDocumentElement());
}
//在给定的根<beans/>元素中注册每个 bean 定义
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//在我们开始处理 bean 定义之前,通过首先处理任何自定义元素类型来允许 XML 可扩展。 此方法是 XML 的任何其他自定义预处理的自然扩展点。默认实现为空。 例如,子类可以覆盖此方法以将自定义元素转换为标准 Spring bean 定义。 实现者可以通过相应的访问者访问解析器的 bean 定义阅读器和底层 XML 资源
preProcessXml(root);
//使用委托对xml解析,具体见下面方法
parseBeanDefinitions(root, this.delegate);
//在我们处理完 bean 定义之后,通过最后处理任何自定义元素类型,允许 XML 可扩展。 此方法是 XML 的任何其他自定义后处理的自然扩展点。默认实现为空。 例如,子类可以覆盖此方法以将自定义元素转换为标准 Spring bean 定义。 实现者可以通过相应的访问者访问解析器的 bean 定义阅读器和底层 XML 资源
postProcessXml(root);
this.delegate = parent;
}
//解析文档中根级别的元素:“import”、“alias”、“bean”
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);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
//对“import”、“alias”、“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字段的解析(具体实现见下面代码)
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
/**
* 处理给定的 bean 元素,解析 bean 定义并将其注册到注册表
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析提供的<bean>元素。 如果解析过程中出现错误,则可能返回null
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//如果适用,通过命名空间处理程序装饰给定的 bean 定义,由委托类进行实现
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
//触发组件注册事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
}
其委托类为BeanDefinitionParserDelegate,decorateBeanDefinitionIfRequired(ele, bdHolder)方法实现如下。
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) {
return decorateBeanDefinitionIfRequired(ele, originalDef, null);
}
/**
* Decorate the given bean definition through a namespace handler, if applicable.
* @param ele the current element
* @param originalDef the current bean definition
* @param containingBd the containing bean definition (if any)
* @return the decorated bean definition
*/
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = originalDef;
// Decorate based on custom attributes first.
NamedNodeMap attributes = ele.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
// Decorate based on custom nested elements.
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;
}
public BeanDefinitionHolder decorateIfRequired(
Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(node);
if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
BeanDefinitionHolder decorated =
handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
if (decorated != null) {
return decorated;
}
}
else if (namespaceUri.startsWith("http://www.springframework.org/")) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
}
else {
// A custom namespace, not to be handled by Spring - maybe "xml:...".
if (logger.isDebugEnabled()) {
logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
}
}
}
return originalDef;
}
至此,通过xml解析成beanDefinition对象,核心过程已经基本解析完毕。
(8)在(1)中的getBeanFactory()方法,调用AbstractRefreshableApplicationContext类的getBeanFactory()方法。
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}