侧边栏壁纸
博主头像
敢敢雷博主等级

永言配命,自求多福

  • 累计撰写 57 篇文章
  • 累计创建 0 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Spring原理---obtainFreshBeanFactory()方法

敢敢雷
2020-03-17 / 0 评论 / 0 点赞 / 562 阅读 / 3,558 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我删除。

obtainFreshBeanFactory()方法的作用是获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等,但是这里的bean并没有初始化出来 只是提取配置信息 定义相关的属性
进入查看源码

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

Spring的源码的命名都是很规范,一般都可以望文生义,进入的一个方法refreshBeanFactory(),刷新BeanFactory,进入方法

refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			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);
		}
	}
  1. 先销毁原有beanFactory;
  2. 创建并初始化BeanFactory;
  3. 加载BeanDefinitions。
    关于这个方法,一个重要的类出现了,他就是DefaultListableBeanFactory

DefaultListableBeanFactory

它是Spring IOC容器的实现,从根源上是beanfactory,但真正可以作为一个可以独立使用的IOC容器还是DefaultListableBeanFactory
经过createBeanFactory()方法后,这个时候我们的BeanFactory初步形成 这也将是管理整个bean的核心接口
setSerializationId(getId())其作用是设置相应的序列化id

customizeBeanFactory()方法

进入customizeBeanFactory()方法

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			//是否允许bean定义的覆盖
			// BeanDefinition 的覆盖问题大家也许会碰到,
			// 就是在配置文件中定义 bean 时使用了相同的 id 或 name
			// ,默认情况下,allowBeanDefinitionOverriding 属性为 null,
			// 如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			//是否允许bean 间的循环依赖
			// A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A
			// 默认情况下,Spring 允许循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的。
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

loadBeanDefinitions()方法

创建BeanFactory最核心的方法就是loadBeanDefinitions()方法,这个方法将开始解析配置 转化为对应的BeanDefinition对象

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

XmlBeanDefinitionReader初始化,无非是初始化自己与父类,在这里最后一个方法loadBeanDefinitions方法开始加载xml文件
进入该方法

loadBeanDefinitions()方法

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		//扩展,默认是null。子类实现
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		//ClassPathXmlApplicationContext构造函数传入的applicationContext.xml
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//正式解析
			reader.loadBeanDefinitions(configLocations);
		}
	}

继续看reader.loadBeanDefinitions方法,查看它是怎么解析的

public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");
		int counter = 0;
		for (String location : locations) {
			counter += loadBeanDefinitions(location);
		}
		return counter;
	}

解析继续调用loadBeanDefinitions方法了,继续查看该方法

开始将XML解析为Resource

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
		//获取当前资源加载器,这里是ClassPathXmlApplicationContext
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
		}
		//ClassPathXmlApplicationContext继承了ResourcePatternResolver
		if (resourceLoader instanceof ResourcePatternResolver) {
			// Resource pattern matching available.
			try {
				//吧Xml解析为Resource
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				//解析resource
				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;
		}
	}

先查看Spring是怎么将XML解析成Resource的把

	public Resource[] getResources(String locationPattern) throws IOException {
		Assert.notNull(locationPattern, "Location pattern must not be null");
		//是不是以classpath*:开始的
		if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
			//以classpath*:开始的
			if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
				// 路径中有?或*号通配符 如classpath*:applicationContext-*.xml
				return findPathMatchingResources(locationPattern);
			}
			else {
				// 路径没有?或*号通配符 如classpath*:applicationContext.xml
				return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
			}
		}
		else {
			//不以classpath*:开始的
			int prefixEnd = locationPattern.indexOf(":") + 1;
			if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
				// 路径中有?或*号通配符
				return findPathMatchingResources(locationPattern);
			}
			else {
				// 路径没有?或*号通配符
				return new Resource[] {getResourceLoader().getResource(locationPattern)};
			}
		}
	}

通过不同的判断,完成了不同的解析,妙呀

解析上一个方法获得Resource

继续回到loadBeanDefinitions方法,下一个解析XML文件方法

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());
		}
		//resourcesCurrentlyBeingLoaded是个ThreadLocal<Set<EncodedResource>>变量
		//得到变量中存放的值,注意每个线程得到的都是一个拷贝
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		//第一次加载是null
		if (currentResources == null) {
			currentResources = new HashSet<EncodedResource>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		//把资源放进set中,纪录已加载内容,不能加载重复内容
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
			//得到该Resource的InputStream
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				//用InputSource封装InputStream,此类是org.xml.sax包下的
				InputSource inputSource = new InputSource(inputStream);
				//如果encodedResource的编码格式不为空,设置InputSource编码格式
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//do..开始真正的解析
				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方法

验证约束文件

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			//加载Xml得到Document对象,也验证了DTD约束
			Document doc = doLoadDocument(inputSource, resource);
			//根据Document注册BeanDefinitions
			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);
		}
}

接着进入registerBeanDefinitions方法

执行注册Resource

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//实例化BeanDefinitionDocumentReader的实现类DefaultBeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//记录注册之前的数值
		int countBefore = getRegistry().getBeanDefinitionCount();
		//执行注册
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//注册的数值
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

进入registerBeanDefinitions方法

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		//获取rootElement
		Element root = doc.getDocumentElement();
		//do。。真正进行注册
		doRegisterBeanDefinitions(root);
	}

真正开始注册获得的XML文件

	protected void doRegisterBeanDefinitions(Element root) {
		//专用来解析的类
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		//判断root的命名空间是不是默认的
		if (this.delegate.isDefaultNamespace(root)) {
			//处理profile属性
			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)) {
					return;
				}
			}
		}
		//扩展,解析前处理
		preProcessXml(root);
		//解析
		parseBeanDefinitions(root, this.delegate);
		//扩展,解析后处理
		postProcessXml(root);
 
		this.delegate = parent;
	}

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

接着进入parseDefaultElement方法

解析四种默认标签import,alias,bean,beans

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);
		}
		//beans
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

我们这里暂时先看一下怎么解析Bean标签的,进入processBeanDefinition方法

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//解析bean标签,返回其包装类
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//bean标签下还有自定义标签再次解析,一般没用过
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 注册
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

可以在这里打个断点,查看下值
image.png
可以发现,Spring已经获得了我们的XML中Bean id为Student的元素了,所以目前重点看parseBeanDefinitionElement方法

获得XML中的值

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		//获取id与name属性
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		//name属性解析为别名
		List<String> aliases = new ArrayList<String>();
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}
		//如果id不存在,别名存在(指name),把name的第一个作为bean的name
		String beanName = id;
		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");
			}
		}
		//检查beanName与别名是否已经被别的bean引用过,即不能定义两个bean的id相同或别名相同
		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		//解析bean属性,并封装为BeanDefinition
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				//如果beanName为空,Spring自动生成beanName
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						//此方法containingBean为null
						//beanName为class+#+数字,比如注册两个类型相同的bean,后面数字是0和1
						beanName = this.readerContext.generateBeanName(beanDefinition);
						//beanClassName设置为别名
						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);
			//根据beanDefinition, beanName, aliasesArray创建BeanDefinitionHolder实例
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}
 
		return null;
	}

这里又出现了一个beanDefinition,打个断点查看值
image.png
这里一切都清楚了,重点代码在parseBeanDefinitionElement中,继续查看

正式获得XML中Bean的值

public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {
 
		this.parseState.push(new BeanEntry(beanName));
		//解析class属性
		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
 
		try {
			//解析parent属性
			String parent = null;
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			//根据className, parent创建GenericBeanDefinition对象用来存储解析出的各种属性
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//解析bean上的属性
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//Description
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			//解析meta标签
			parseMetaElements(ele, bd);
			//解析lookup-method属性
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			//解析replace-method属性
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
			//解析constructor-arg标签
			parseConstructorArgElements(ele, bd);
			//解析property标签
			parsePropertyElements(ele, bd);
			//解析qualifier标签
			parseQualifierElements(ele, bd);
 
			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();
		}
 
		return null;
	}

有兴趣的朋友可以自己查看先具体解析代码了,这里就不一一赘述了
所以bean解析完成后返回一个AbstractBeanDefinition,这个实例已经包含了所有解析到的属性
最后,我们都知道所以的Bean都会装入一个beanDefinitionMap中,下面看看是怎么装入的

Bean装入Map中

回到方法

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//解析bean标签,返回其包装类
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//bean标签下还有自定义标签再次解析,一般没用过
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 注册
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

查看方法registerBeanDefinition

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		//BeanDefinition注册
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
 
		// 别名注册
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
	}

最后进入registerBeanDefinition方法

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");
 
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				//验证针对methodoverrides进行验证,因为基本不设置这两个属性,不做解析
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
 
		BeanDefinition oldBeanDefinition;
		//beanDefinitionMap是否存在beanName的beanDefinition
		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 + "]");
				}
			}
			//beanName为key,beanDefinition为value存入map
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			//判断工厂Bean是否已经处于创造阶段并且被标记,是在没遇到过的场景
			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<String>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// Still in startup registration phase
				//beanName为key,beanDefinition为value存入map
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//beanName加入到beanDefinitionNames中
				this.beanDefinitionNames.add(beanName);
				//清除缓存中的此beanName
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
 
		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

经过大量的判断后,符合条件的会装入beanDefinitionMap中至此,注册完了,这里的注册类是DefaultListableBeanFactory,此类中的beanDefinitionMap属性存储了beanName与BeanDenifition的映射,beanDefinitionNames存储了所有的beanName

总结

  • obtainFreshBeanFactory方法的作用获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
  • 注册类是DefaultListableBeanFactory此类中的beanDefinitionMap属性存储了beanName与BeanDenifition的映射
  • beanDefinitionNames存储了所有的beanName
  • 所以的Bean都被装入beanDefinitionMap中
  • obtainFreshBeanFactory方法这里的bean并没有初始化出来 只是提取配置信息定义相关的属性

image.png

0

评论区