spring源码解析(三):refresh()核心之obtainFreshBeanFactory()方法解析

  • Post author:
  • Post category:其他




spring refresh()中obtainFreshBeanFactory()方法解析

obtainFreshBeanFactory()方法是refresh()方法中的核心之一。

作用:

初始化beanFactory,加载并解析配置

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//1.初始化beanFactory,并执行加载和解析配置操作
		refreshBeanFactory();
		//返回beanFactory实例
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

obtainFreshBeanFactory()方法中做了二件事:

  1. refreshBeanFactory():创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义
  2. getBeanFactory():返回beanFactory实例



一. refreshBeanFactory():刷新beanFactory

初始化beanFactory,并执行加载和解析配置操作

进入到refreshBeanFactory()方法,分析refreshBeanFactory()方法的具体实现:

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    ...
    
    @Override
	protected final void refreshBeanFactory() throws BeansException {
		//判断是否存在beanFactory
		if (hasBeanFactory()) {
		    // 注销所有的单例
			destroyBeans();
			//重置beanFactory
			closeBeanFactory();
		}
		try {
		    //创建beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//指定序列化id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
			beanFactory.setSerializationId(getId());
			//定制BeanFactory
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
	...
}

refreshBeanFactory()方法中做了四件事情:

  1. 如果有bean工厂,销毁bean以及关闭bean工厂
  2. createBeanFactory():创建beanFactory
  3. beanFactory.setSerializationId(getId()):指定序列化Id
  4. customizeBeanFactory():定制BeanFactory
  5. loadBeanDefinitions():加载bean定义



1、如果有bean工厂,销毁bean以及关闭bean工厂



1.1、hasBeanFactory():判断是否存在beanFactory

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    ...

	/** Bean factory for this context */
	@Nullable
	private DefaultListableBeanFactory beanFactory;
    ...
    
    protected final boolean hasBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			return (this.beanFactory != null);
		}
	}
}

如果this.beanFactory != null,则注销所有的单例和重置beanFactory。



1.2、destroyBeans():注销所有的单例

protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}

进去到destroySingletons():

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    ...
    
	@Override
	public void destroySingletons() {
	    //调用父类的销毁方法销毁单例bean
		super.destroySingletons();
		//清空手工注册的beanName的缓存
		this.manualSingletonNames.clear();
		//清空类型-->beanName的映射缓存
		clearByTypeCache();
	}
}

父类的销毁方法,destroySingletons():

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    ...
    
    public void destroySingletons() {
		if (logger.isDebugEnabled()) {
			logger.debug("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {
		    //设置正在销毁的标记为true
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
		    //遍历销毁之前注册的所有disposableBean
			destroySingleton(disposableBeanNames[i]);
		}
        //清空beanName --> 它包含的所有内部beanName集合的映射缓存
		this.containedBeanMap.clear();
		//清空beanName --> 它依赖的所有beanName集合的映射缓存
		this.dependentBeanMap.clear();
		//清空beanName --> 依赖它的所有beanName集合的映射缓存
		this.dependenciesForBeanMap.clear();
        //清空所有注册的缓存
		clearSingletonCache();
	}
	
	//clearSingletonCache():清空所有注册的缓存的方法
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
		    // 清空单例bean缓存
			this.singletonObjects.clear();
			// 清空单例工厂缓存
			this.singletonFactories.clear();
			// 清空提前暴露的beanName --> bean的映射缓存
			this.earlySingletonObjects.clear();
			// 清空已经注册的单例bean缓存
			this.registeredSingletons.clear();
			// 设置正在销毁的标记为false
			this.singletonsCurrentlyInDestruction = false;
		}
	}
	...
}

destroySingleton():销毁之前注册的所有disposableBean

public void destroySingleton(String beanName) {
        //清除bean的相应缓存
		removeSingleton(beanName);

		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
		    //移除并获取disposableBean
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		//销毁
		destroyBean(beanName, disposableBean);
	}


1.2.1、removeSingleton(beanName):清除bean的相应缓存
protected void removeSingleton(String beanName) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}


1.2.2、destroyBean():销毁bean实例
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		Set<String> dependencies;
		synchronized (this.dependentBeanMap) {
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		if (dependencies != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			for (String dependentBeanName : dependencies) {
			    // 首选递归销毁所有当前bean依赖的bean
				destroySingleton(dependentBeanName);
			}
		}

		if (bean != null) {
			try {
			    //销毁bean
				bean.destroy();
			}
			catch (Throwable ex) {
				logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
			}
		}

		Set<String> containedBeans;
		synchronized (this.containedBeanMap) {
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
			    // 递归销毁当前bean包含的所有内部bean
				destroySingleton(containedBeanName);
			}
		}

		synchronized (this.dependentBeanMap) {
		    // 遍历找出所有依赖当前bean的列表,将当前bean从被依赖的列表中移除
			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);
	}



1.3、closeBeanFactory():重置beanFactory为null

@Override
	protected final void closeBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory != null) {
				this.beanFactory.setSerializationId(null);
				this.beanFactory = null;
			}
		}
	}

该方法令beanFactory置为null。



2、createBeanFactory():创建beanFactory

进入到createBeanFactory()方法中:

protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

调试发现:getInternalParentBeanFactory() == null,因此创建DefaultListableBeanFactory。



3、beanFactory.setSerializationId(getId()):指定序列化id

    beanFactory.setSerializationId(getId());

    //其中getId():
    @Override
	public String getId() {
		return this.id;
	}
	
	//this.id为:
	private String id = ObjectUtils.identityToString(this);



4、customizeBeanFactory():定制BeanFactory

对BeanFactory的扩展,在基本容器的基础上,增加了是否允许覆盖是否允许扩展的设置

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
	    //是否允许覆盖同名称的不同定义的对象
		if (this.allowBeanDefinitionOverriding != null) {
		    // 如果属性allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//是否允许bean之间存在循环依赖
		if (this.allowCircularReferences != null) {
		    // 如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}



5、loadBeanDefinitions():加载bean定义

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

    ...
    
    @Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	    //为指定beanFactory创建XmlBeanDefinitionReader(加载解析bean)
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        
        //对beanDefinitionReader进行环境变量的设置
		beanDefinitionReader.setEnvironment(getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        
        //对beanDefinitionReader进行设置,空方法
		initBeanDefinitionReader(beanDefinitionReader);
		//设置loadBeanDefinitions的配置文件
		loadBeanDefinitions(beanDefinitionReader);
	}
	...

}

进入到initBeanDefinitionReader(beanDefinitionReader)中:

protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
	}

发现啥都没有,纯粹是给子类重写的。

进入到loadBeanDefinitions()方法中:

//XmlWebApplicationContext

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        //获取配置位置
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			for (String configLocation : configLocations) {
				reader.loadBeanDefinitions(configLocation);
			}
		}
	}



5.1、获取配置信息

查看getConfigLocations()方法:

    @Nullable
	protected String[] getConfigLocations() {
		return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
	}


5.1.1、this.configLocations不为null

调试发现:configLocations = [“classpath:spring.xml”]。


getConfigLocations()为什么等于”classpath:spring.xml”?

细心的同学应在spring源码解析(一)中发现了线索:

在configureAndRefreshWebApplicationContext()方法中

        //读取web.xml中Spring配置文件路径CONFIG_LOCATION_PARAM = “contextConfigLocation”
		String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
		if (configLocationParam != null) {
			wac.setConfigLocation(configLocationParam);
		}


5.1.2、this.configLocations为null

如果this.configLocations为null,则进入getDefaultConfigLocations()方法,而XmlWebApplicationContext类中重写了AbstractRefreshableConfigApplicationContext类中的getDefaultConfigLocations()方法:

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

    ...
    
    @Override
	protected String[] getDefaultConfigLocations() {
		if (getNamespace() != null) {
		    // "/WEB-INF/xxx.xml"
			return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
		}
		else {
		    // "/WEB-INF/applicationContext.xml"
			return new String[] {DEFAULT_CONFIG_LOCATION};
		}
	}
}

其中:

    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

	public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

	public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

因此,如果不在web.xml中设置contextConfigLocation的话,就会读取默认contextConfigLocation的值为:”/WEB-INF/applicationContext.xml”。

 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>



5.2、获取资源完成定位工作

继续进入reader.loadBeanDefinitions(configLocation)里面:

    //抽象类AbstractBeanDefinitionReader
    
    @Override
	public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}

继续进入,为每个bean生成BeanDefinition

//抽象类AbstractBeanDefinitionReader

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {

        //获取资源
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
		}

        //resourceLoader是ClasspathXmlApplicationContext,ApplicationContext接口本身继承了ResourcePatternResolver接口
		if (resourceLoader instanceof ResourcePatternResolver) {
			try {
			    //location转为Resource完成定位工作
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources);
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
				}
				return loadCount;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// Can only load single resources by absolute URL.
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
			}
			return loadCount;
		}
	}



5.2.1、getResourceLoader():获取资源
	@Override
	@Nullable
	public ResourceLoader getResourceLoader() {
		return this.resourceLoader;
	}


this.resourceLoader的是从哪里获取的?

细心的同学看上面的《5. loadBeanDefinitions():加载bean定义》中有这么一句:

    beanDefinitionReader.setResourceLoader(this);

    //点击进去:
    public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

其中的this就是XmlWebApplicationContext上下文。



5.2.2、getResources():location转为Resource完成定位工作

esource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location)将location转成了Resource[],这一步完成了资源的定位工作。

它调用了PathMatchingResourcePatternResolver的getResources方法:

	@Override
	public Resource[] getResources(String locationPattern) throws IOException {
		Assert.notNull(locationPattern, "Location pattern must not be null");
		//是否以classpath*:开头
		if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
			if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
				return findPathMatchingResources(locationPattern);
			}
			else {
				return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
			}
		}
		else {
			int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
					locationPattern.indexOf(':') + 1);
			if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
				return findPathMatchingResources(locationPattern);
			}
			else {
				return new Resource[] {getResourceLoader().getResource(locationPattern)};
			}
		}
	}

根据location写法,解析方式也不同:

  1. 前缀为classpath*

    1. 文件路径路径中包含*和?

      调用findPathMatchingResources方法
    2. 文件路径中不含*和?

      调用findAllClassPathResources方法
  2. 前缀为classpath

    1. 文件路径路径中包含*和?

      调用findPathMatchingResources方法
    2. 文件路径中不含*和?

      调用DefaultResourceLoader的getResource方法new一个ClasspathResource并 返回,如果资源文件根本就不存在,此处也不会校验。



5.3、根据资源加载bean的定义

把读取的”classpath:spring.xml”转换成resource之后,加载bean:loadBeanDefinitions(resources);

	
	@Override
	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;
	}

以上是多个资源遍历加载,继续进入到loadBeanDefinitions(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 {
		    //读取encodedResource流
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//继续加载bean的定义
				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();
			}
		}
	}

进入到doLoadBeanDefinitions(inputSource, encodedResource.getResource())中:

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			Document doc = doLoadDocument(inputSource, resource);
			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);
		}
	}


这里把读取的”classpath:spring.xml”转换成的resource转换成Document文件,进入registerBeanDefinitions(doc, resource):

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

进入到documentReader.registerBeanDefinitions(doc, createReaderContext(resource));中:

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

继续doRegisterBeanDefinitions(root);:

protected void doRegisterBeanDefinitions(Element root) {
		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;
				}
			}
		}

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

		this.delegate = parent;
	}

进入到parseBeanDefinitions(root, this.delegate)中,此方法就是解析xml的方法:

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);
		}
	}

如图中所显示,解析web.xml中的spring.xml时读取到

其中delegate.isDefaultNamespace(ele)进入查看下是什么意思:

	public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
	
	public boolean isDefaultNamespace(@Nullable String namespaceUri) {
		return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
	}

	public boolean isDefaultNamespace(Node node) {
		return isDefaultNamespace(getNamespaceURI(node));
	}

这个判断条件的意思就是判断spring.xml中是否有http://www.springframework.org/schema/beans(bean、beans、import、alias)定义的存在。

如果存在,则进入到parseDefaultElement(ele, delegate)中:

	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

这里是四种判断条件:

public static final String IMPORT_ELEMENT = "import";

public static final String ALIAS_ELEMENT = "alias";

public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT;
(public static final String BEAN_ELEMENT = "bean";)

public static final String NESTED_BEANS_ELEMENT = "beans";



二. getBeanFactory():返回beanFactory实例

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

直接返回当前上下文的beanFactory。


上一章:spring源码解析(二):refresh()源码解析



下一章:spring源码解析(四):refresh()中obtainFreshBeanFactory()(1、解析spring.xml))



版权声明:本文为u011151359原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。