spring refresh()方法详解2之obtainFreshBeanFactory()

 obtainFreshBeanFactory方法实现代码如下:

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	    // 1.刷新 BeanFactory --具体实现见AbstractRefreshableApplicationContext
		refreshBeanFactory();
	    // 2.返回刷新后的 BeanFactory
		return getBeanFactory();
	}

1 refreshBeanFactory方法

	/**
	 * 刷新 BeanFactory
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
	        // 1.判断是否已经存在 BeanFactory,如果存在则先销毁、关闭该 BeanFactory
                // 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
		// ApplicationContext 是否有 BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();	//销毁所有 Bean
			closeBeanFactory();//关闭 BeanFactory
		}
		try {
	                // 2.创建一个新的BeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());	// 用于 BeanFactory 的序列化
			// 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
			customizeBeanFactory(beanFactory);
	                // 3.加载 bean 定义。
			loadBeanDefinitions(beanFactory);	//AbstractXmlApplicationContext类中实现
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

1.1 判断beanFactory是否存在,若存在先销毁关闭

1.hasBeanFactory 判断beanFactory是否已存在,我们第一次启动时hasBeanFactory 应该是返回false

	/** Synchronization monitor for the internal BeanFactory. */
	private final Object beanFactoryMonitor = new Object();

        /**
	 * 判断beanFactory是否存在
	 */
	protected final boolean hasBeanFactory() {
		synchronized (this.beanFactoryMonitor) { //加锁
			return (this.beanFactory != null);	//直接返回beanFactory 是否为null
		}
	}

2.destroyBeans销毁所有已创建bean,我们直接ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");启动容器是不会执行到该方法的,但是启动后调用context.refresh();会进入到条件中执行该方法。

	/**
	 * 销毁所有bean  前提条件:beanFactory存在
	 */
	protected void destroyBeans() {
		//getBeanFactory 在AbstractRefreshableApplicationContext中实现
                //destroySingletons 在DefaultListableBeanFactory中实现
		getBeanFactory().destroySingletons();
	}
//========================AbstractRefreshableApplicationContext > getBeanFactory===========
	/**
	 * 获取beanFactory
	 */
	@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		synchronized (this.beanFactoryMonitor) {//加锁
			if (this.beanFactory == null) {	//判断是否为null 为null则抛出异常
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;	//返回beanFactory
		}
	}
//========================DefaultListableBeanFactory > destroySingletons===========

	/**
	 * DefaultListableBeanFactory--销毁bean
	 */
	@Override
	public void destroySingletons() {
		super.destroySingletons();	//调用父类方法销毁Singletons的Bean
		//更新ManualSingletonNames
		updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
		clearByTypeCache();	//清空ByType的缓存
	}

下面分析destroySingletons方法

2.1 super.destroySingletons()

	/**
	 * DefaultSingletonBeanRegistry:销毁所有单例bean
	 */
	public void destroySingletons() {
		if (logger.isTraceEnabled()) {
			logger.trace("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {	//加锁
			this.singletonsCurrentlyInDestruction = true;	//标记设置为true
		}

		String[] disposableBeanNames;	//所有待销毁的beanName
		synchronized (this.disposableBeans) {	//加锁
			//拿出disposableBeans中的所有key,放入disposableBeanNames数组中
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());	
		}
		//遍历disposableBeanNames数组 调用destroySingleton方法销毁bean
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			destroySingleton(disposableBeanNames[i]);
		}

		//清空以下几个集合
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();

		clearSingletonCache();
	}

	/**
	 * 调用clearSingletonCache方法清空单例的缓存
	 */
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

2.2 updateManualSingletonNames(Set::clear, set -> !set.isEmpty())

	/**
	 * 先判断manualSingletonNames是否为空,
	 * 	不为空则根据manualSingletonNames新建一个set,然后把这个set清空,然后在把manualSingletonNames指向这个set
	 * @param action 一个消费型接口  这里是Set::clear  调用Set的clear方法
	 * @param condition	一个断言型接口	这里是set -> !set.isEmpty()  判断set是否非空
	 */
	private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
		if (hasBeanCreationStarted()) {	//判断alreadyCreated是否非空
			synchronized (this.beanDefinitionMap) {	//加锁
				if (condition.test(this.manualSingletonNames)) {	//断言manualSingletonNames是否非空
					//根据manualSingletonNames新建一个LinkedHashSet  updatedSingletons
					Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
					action.accept(updatedSingletons); //对updatedSingletons进行消费  清空updatedSingletons
					this.manualSingletonNames = updatedSingletons;//将manualSingletonNames指向消费后的updatedSingletons 是一个空集合
				}
			}
		}
		else {//alreadyCreated为空
			if (condition.test(this.manualSingletonNames)) {//断言manualSingletonNames 如果manualSingletonNames非空
				action.accept(this.manualSingletonNames);	//对manualSingletonNames进行消费	清空manualSingletonNames
			}
		}
	}

2.3 clearByTypeCache()

	/**
	 * 清空allBeanNamesByType与singletonBeanNamesByType两个集合
	 */
	private void clearByTypeCache() {
		this.allBeanNamesByType.clear();
		this.singletonBeanNamesByType.clear();
	}

3 closeBeanFactory 关闭 BeanFactory

	/**
	 * 关闭 BeanFactory
	 */
	@Override
	protected final void closeBeanFactory() {
		synchronized (this.beanFactoryMonitor) {	//加锁
			if (this.beanFactory != null) {	//beanFactory非空
				this.beanFactory.setSerializationId(null);	//清空集合序列化ID 
				this.beanFactory = null;	//置空beanFactory
			}
		}
	}
//==================================================================================
	/**
	 * 设置集合序列化ID 
	 */
	public void setSerializationId(@Nullable String serializationId) {
		if (serializationId != null) {	//serializationId非空
			serializableFactories.put(serializationId, new WeakReference<>(this));	//put
		}
		else if (this.serializationId != null) {	//this.serializationId非空
			serializableFactories.remove(this.serializationId);	//remove
		}
		this.serializationId = serializationId;	//设置this.serializationId 为 serializationId
	}

1.1.2 创建一个新的BeanFactory并设置其属性

1.createBeanFactory创建BeanFactory

	/**
	 * 创建BeanFactory
	 */
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
	/**
	 * 获取父BeanFactory 
	 */
	@Nullable
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
	}

2.beanFactory.setSerializationId(getId());    // 用于 BeanFactory 的序列化

3.customizeBeanFactory设置 BeanFactory 的两个配置属性

	/**
	 * beanFactory配置
	 */
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			// 是否允许 Bean 定义覆盖
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			// 是否允许 Bean 间的循环依赖
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

1.3 加载 bean 定义

	/**
	 * 加载 bean 定义
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	    // 1.为指定BeanFactory创建XmlBeanDefinitionReader
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	    // 2.使用此上下文的资源加载环境配置 XmlBeanDefinitionReader
		beanDefinitionReader.setEnvironment(this.getEnvironment());
	    // resourceLoader赋值为XmlWebApplicationContext
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 初始化 BeanDefinitionReader
		initBeanDefinitionReader(beanDefinitionReader);
		
	    // 3.加载 bean 定义
		loadBeanDefinitions(beanDefinitionReader);
	}

1.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory)

        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//======================================================================
	public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
		super(registry);
	}
//======================================================================
	protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		// Determine ResourceLoader to use.
		if (this.registry instanceof ResourceLoader) {
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}

		// Inherit Environment if possible
		if (this.registry instanceof EnvironmentCapable) {
			this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
		}
		else {
			this.environment = new StandardEnvironment();
		}
	}

主要是初始化registry,resourceLoader和environment,我们这里new ClassPathXmlApplicationContext("spring.xml")启动容器的方式两个判断条件都会走到else里。

2.主要是对beanDefinitionReader进行各种配置

3.loadBeanDefinitions(beanDefinitionReader)加载 bean 定义,代码如下:

	/**
	 * 加载 bean 定义
	 */
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
	    //获取资源Resource
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
            // 根据Resource加载 bean 定义
			reader.loadBeanDefinitions(configResources);
		}
		// 1.获取配置文件路径
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//2根据配置文件configLocations加载bean定义
			reader.loadBeanDefinitions(configLocations);
		}
	}

	/**
	 * 这里直接返回null
	 */
	@Nullable
	protected Resource[] getConfigResources() {
		return null;
	}

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

我们这里追一下reader.loadBeanDefinitions(String [] configLocations)的源码

	/**
	 * 根据配置文件路径加载
	 */
	@Override
	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");	//校验非null
		int count = 0;
		for (String location : locations) {	//遍历
			count += loadBeanDefinitions(location);	//根据location加载bean定义
		}
		return count;
	}

	@Override
	public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}
	/**
	 * 加载bean定义
	 */
	public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
		ResourceLoader resourceLoader = getResourceLoader();	//获取ResourceLoader
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
		}

		if (resourceLoader instanceof ResourcePatternResolver) {	//resourceLoader是否为ResourcePatternResolver类型
			try {
				//根据resourceLoader获取Resource
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int count = loadBeanDefinitions(resources);	//调用loadBeanDefinitions(Resource[] resources)
				if (actualResources != null) {
					Collections.addAll(actualResources, resources);	//将resources中数据添加到actualResources中
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
				}
				return count;	//返回
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			Resource resource = resourceLoader.getResource(location);	//获取Resource
			int count = loadBeanDefinitions(resource);	//加载bean定义
			if (actualResources != null) {
				actualResources.add(resource);//resource添加到actualResources中
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
			}
			return count;//返回
		}
	}

这里我们发现会调用loadBeanDefinitions(resources);或loadBeanDefinitions(resource);参数是Resource类型或Resource[] 类型继续追源码

	/**
	 * 根据Resource加载bean定义
	 */
	@Override
	public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		Assert.notNull(resources, "Resource array must not be null");	//null校验
		int count = 0;
		for (Resource resource : resources) {	//遍历
			count += loadBeanDefinitions(resource);	//根据resource加载bean定义
		}
		return count;
	}

	/**
	 * 根据Resource加载bean定义
	 */
	@Override
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}

	/**
	 * 根据EncodedResource加载bean定义
	 */
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");	//null校验
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);
		}

		//从resourcesCurrentlyBeingLoaded中get数据
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<>(4);	//currentResources为空就初始化一个
			this.resourcesCurrentlyBeingLoaded.set(currentResources);	//currentResources放入resourcesCurrentlyBeingLoaded中
		}
		if (!currentResources.add(encodedResource)) {	//添加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);	//包装成InputSource
				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();
			}
		}
	}


	/**
	 * 加载bean定义
	 */
	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			Document doc = doLoadDocument(inputSource, resource);	//转换成Document结构
			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);
		}
	}

继续追溯源码吧

	/**
	 * 加载bean定义
	 */
	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//获取BeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//获取注册表中定义的bean的数目
		int countBefore = getRegistry().getBeanDefinitionCount();
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;	//计算成功加载数量
	}
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		doRegisterBeanDefinitions(doc.getDocumentElement());	//加载操作
	}

	/**
	 * 加载bean定义
	 */
	@SuppressWarnings("deprecation")  // for Environment.acceptsProfiles(String...)
	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.isDebugEnabled()) {
						logger.debug("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;
	}


	/**
	 * 加载操作
	 */
	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
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);	//默认的标签解析  根据节点类型不同进行不同操作
					}
					else {
						delegate.parseCustomElement(ele);	//自定义标签的解析和注册
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);//自定义标签的解析和注册
		}
	}

	/**
	 * 根据节点类型不同进行不同操作
	 */
	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);	//import节点处理
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);	//alias节点处理
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);	//bean节点处理
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {	//beans节点处理
			// recurse
			doRegisterBeanDefinitions(ele);	//回调到doRegisterBeanDefinitions()处理bean节点
		}
	}

这里我们看一下bean节点的处理

	/**
	 * bean节点处理
	 */
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 注册bean定义
				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));
		}
	}

	/**
	 * 注册bean
	 */
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//registry注册器注册BeanDefinition
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 别名注册
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

到这里,加载配置,生成bean定义就完成了让我们回到obtainFreshBeanFactory方法的:2.返回刷新后的 BeanFactory

2.getBeanFactory

这里没什么好说的,就是把第一步里创建的beanFactory返回

	/**
	 * 获取beanFactory
	 */
	@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		synchronized (this.beanFactoryMonitor) {//加锁
			if (this.beanFactory == null) {	//判断是否为null 为null则抛出异常
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;	//返回beanFactory
		}
	}

猜你喜欢

转载自blog.csdn.net/luo_mu_hpu/article/details/107317654
今日推荐