前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >彻底弄懂Spring中Bean的解析、创建和使用

彻底弄懂Spring中Bean的解析、创建和使用

作者头像
石奈子
发布2020-06-28 11:09:35
2.4K0
发布2020-06-28 11:09:35
举报

Spring加载Bean、实例化Bean、获取Bean流程

本文旨在通过分析源码的方式,来剖析Spring加载Bean、实例化Bean、获取Bean的流程,部分核心内容会在源码中说明。内容比较枯燥,慎入!

  • 第一步,启动一个Spring项目

Spring启动入口

官方文档中我们可以获取到下面这种Spring的启动方式。

我们传入一个test.xml文件

代码语言:javascript
复制
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/spring/test.xml");
  • xml文件内容
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    <bean id="stringutil" class="com.baigt.utils.StringUtils"></bean>
</beans>
  • bean对象(StringUtils)
代码语言:javascript
复制
public class StringUtils{
// some code
}

源码分析之Bean解析

从源码层面分析Bean解析过程、实例化过程、

入口 ClassPathXmlApplicationContext

先看下类图,后续源码中会反复用到不同层级中的代码。

启动类图
启动类图
ClassPathXmlApplicationContext实例化
代码语言:javascript
复制
	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}
	// 省略some code 
	
	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {

	super(parent);
	//当前ClassPathXmlApplicationContext也是resource的子类
	setConfigLocations(configLocations);
	//前边传入的refresh为true,执行 refresh方法
	if (refresh) {
		refresh();
	}
}

AbstractApplicationContext#refresh

org.springframework.context.support.AbstractApplicationContext#refresh,AbstractApplicationContext是ClassPathXmlApplicationContext的父类。而这里的refresh则是覆写了ConfigurableApplicationContext的refresh方法

代码语言:javascript
复制
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// refresh的前置准备,比如设置startTime,开启激活状态、关闭close状态等等等
			prepareRefresh();

			//告诉子类去刷新内容Bean工厂(从类图中可以明显看出来入口类实例也是个bean工厂)
			// 观察和刷新BeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//提前设置一些在该context中使用的属性,比如Classloader、Callback、environment等
			prepareBeanFactory(beanFactory);

			try {
				// 通知context子类,后置处理beanFactory。比如用一系列的Webcontext子类
				postProcessBeanFactory(beanFactory);

				// 将BeanFactoryPostProcessor在当前Context中注册为Bean
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册BeanPostProcessor来拦截Bean创建的后置处理。
				registerBeanPostProcessors(beanFactory);

				// 为当前Context初始化MessageSource
				initMessageSource();

				// 为当前context初始化应用事件广播
				initApplicationEventMulticaster();

				// 初始化其他特殊的bean对象 比如webcontext
				onRefresh();

				// 检查监听Bean 并发布他们(ApplicationListener)
				registerListeners();

				// 实例化BeanFactory中所有的其他的单例对象集合(非延迟的)
				finishBeanFactoryInitialization(beanFactory);

				// 最后发布LifecycleProcessor和ContextRefreshedEvent事件
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 失败销毁bean
				destroyBeans();

				// Reset 'active' flag.
				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...
				resetCommonCaches();
			}
		}
	}
BeanFactory创建

如果你了解BeanFactory,会知道此类是Spring重要的基础对象.

扩展BeanFactory讲解
  • 是访问Spring Bean容器的根接口。是一个基础的client,功能更多的有比如ListableBeanFactory、ConfigurableBeanFactory。
  • 这个接口的实现类,一般都会持有多个BeanDefinition对象信息,比如数量,Scope、实例、名称等。(可对比ListableBeanFactory)
  • BeanFactory是Application组件的一个中央注册处(登记)
  • 通常来说,BeanFactory会加载来自比如Xml的配置源中的Bean数据,并存储在工厂中。
  • 如果是HierarchicalBeanFactory的话,ListableBeanFactory中的几乎所有方法都会检查是否是父工厂。
  • beanFactory应该支持以下的标准生命周期
代码语言:javascript
复制
<li>BeanNameAware's {@code setBeanName}
 * <li>BeanClassLoaderAware's {@code setBeanClassLoader}
 * <li>BeanFactoryAware's {@code setBeanFactory}
 * <li>EnvironmentAware's {@code setEnvironment}
 * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
 * <li>ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)
 * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)
 * <li>MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)
 * <li>ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)
 * <li>ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)
 * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
 * <li>InitializingBean's {@code afterPropertiesSet}
 * <li>a custom init-method definition
 * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
 * </ol>
 *
 * <p>On shutdown of a bean factory, the following lifecycle methods apply:
 * <ol>
 * <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
 * <li>DisposableBean's {@code destroy}
 * <li>a custom destroy-method definition
AbstractApplicationContext#obtainFreshBeanFactory
  • 继续BeanFactory创建过程分析
代码语言:javascript
复制
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 如果已经有了工厂直接销毁,然后再建工厂
		refreshBeanFactory();
		//基本是从上边创建的beanFactory拿的
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
AbstractRefreshableApplicationContext#refreshBeanFactory

org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory。如果已经有了工厂直接销毁,然后再建工厂。新建工厂会loadBeanDefinitions.

扩展BeanDefinition术语

BeanDefinition描述一个Bean实例具有的属性,比如Scope(单例还是Prototype),beanClassName、是否延迟加载,依赖等等等(还有些其他的属性)。当然这个是最小的BeanDefiniton接口,比较常用的子类实现有RootBeanDefinition,功能更为强大。

  • 回到BeanFactory创建。
代码语言:javascript
复制
	protected final void refreshBeanFactory() throws BeansException {
		//如果有bean工厂销毁bean,关闭bean工厂
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建 DefaultListableBeanFactory  而此工厂是BeanDefinitionRegistry的一个子类
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			//加载BeanDefinition(该例中是解析Xml中的Bean标签,并装载到BeanDefinition中)
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				//赋值给Context中的beanFactory
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			
		}
	}
AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory)

org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)。 我们这里只是当前Xml方式的示例会进入此处。

代码语言:javascript
复制
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 使用给定的beanFactory(BeanDefinitionRegistry) 来创建XmlBeanDefinitionReader实例
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		// ClassPathXmlApplicationContext也是一个ResouceLoader
		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);
		// 通过XmlBeanDefinitionReader解析生成BeanDefinition
		loadBeanDefinitions(beanDefinitionReader);
	}
	
	//接上
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		// 入口中传入的test.xml被存放在this.configLocations上,这里可以拿到。
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}
AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)

org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)。根据传入路径读取。

代码语言:javascript
复制
	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;
	}

	//接上
		public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}
	// 接上  
	// 从类图中可知 this对象(ClassPathXmlApplicationContext) 也是DefaultResourceLoader实例,已经被set进reader中,所以走else逻辑
	public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
		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 {
				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 {
			// 只能加载从绝对路径加载单resouce   location为我们传入的test.xml 路径
			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;
		}
	}
XmlBeanDefinitionReader#loadBeanDefinitions(Resource)

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource) 。从xml中加载Bean

代码语言:javascript
复制
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}

	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		//... 省略代码
		try {
			// 前边我们传入的test.xml的输入流
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//真正的从xml中load bean definition
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			
		}
	}

// 接上
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			// 解析xml文件为Document
			Document doc = doLoadDocument(inputSource, resource);
			return registerBeanDefinitions(doc, resource);
		}
		catch (BeanDefinitionStoreException ex) {
			// 省略代码
		}
	}
// 接上
	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		int countBefore = getRegistry().getBeanDefinitionCount();
		// 从reader中注册BeanDefinition到工厂
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}
DefaultBeanDefinitionDocumentReader#registerBeanDefinitions

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions。注册BeanDefinition对象。

代码语言:javascript
复制
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		doRegisterBeanDefinitions(root);
	}
	// 接上  通过委托模式和模板模式来解析xml   
	protected void doRegisterBeanDefinitions(Element root) {
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		// 省略代码....

		preProcessXml(root);
		//只关注此代码
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);

		this.delegate = parent;
	}
//接上  只关注Spring自带的解析
	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)) {
						// Spring自带的标签解析
						parseDefaultElement(ele, delegate);
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}
	//接上  支持解析Import标签、alias 、bean、beans嵌套的
	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)) {
			//示例中应关注此处解析bean标签
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

	//接上 处理BeanDefinition
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		// 核心解析步骤(使用委托模式)
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			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));
		}
	}
BeanDefinitionParserDelegate#parseBeanDefinitionElement(Element)

org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element)。真正的xml转BeanDefinition逻辑代码。

代码语言:javascript
复制
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
		return parseBeanDefinitionElement(ele, null);
	}
	// 解析xml,生成AbstractBeanDefinition对象实例,交给AbstractBeanDefinition管理
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<String>();
		//如果使用了name标签,将name作为别名
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

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

		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		// 解析元素内容成BeanDefinition
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						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.
						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);
			//包装成BeanDefinitionHolder对象
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}

	public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {

		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}

		try {
			String parent = null;
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			//创建基本的BeanDefinition对象,设置beanName,ParentName,ClassLoader等信息
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//解析比如singleton、lazy-init、scope、abstract等等属性标签,并设置到BeanDefinition(以下简称为bd)实例中
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			// 解析description标签 设置到Bd对象中
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			// 解析meta标签 设置到bd对象中
			parseMetaElements(ele, bd);
			
			// 解析lookup-method标签 设置到bd对象中
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			// 解析replaced-method标签 设置到bd对象中
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
			// 解析constructor-arg标签 设置到bd对象中
			parseConstructorArgElements(ele, bd);
			// 解析property标签 设置到bd对象中(比如我们使用datasource时注入的url、user、pwd这些property)
			parsePropertyElements(ele, bd);
			// 解析qualifier标签 设置到bd对象中
			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;
	}

	protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
			throws ClassNotFoundException {

		return BeanDefinitionReaderUtils.createBeanDefinition(
				parentName, className, this.readerContext.getBeanClassLoader());
	}
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#createBeanDefinition

	public static AbstractBeanDefinition createBeanDefinition(
			String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setParentName(parentName);
		if (className != null) {
			if (classLoader != null) {
				bd.setBeanClass(ClassUtils.forName(className, classLoader));
			}
			else {
				bd.setBeanClassName(className);
			}
		}
		return bd;
	}
返回到DefaultBeanDefinitionDocumentReader#processBeanDefinition

一层层调用返回,返回到org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition。我们继续分析BeanDefinitionReaderUtils.registerBeanDefinition部分。这个部分是真正把BeanDefiniton关联到当前Context中的步骤。

代码语言:javascript
复制
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			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);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition

将Holder持有的BeanDefiniton交给BeanDefinitionRegistry(当前context也是个registry实例,是DefaultListableBeanFactory)持有

代码语言:javascript
复制
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		// 核心关注这块的逻辑
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

首次进入此方法,1. beanDefinition是AbstractBeanDefinition类型的实例,进行validate;2. oldBeanDefinition为空,执行else代码 3. BeanCreationStarted为false,执行beanDefinitionMap、beanDefinitionNames、manualSingletonNames值操作。

  • 特别注意这几个对象(beanDefinitionMap、beanDefinitionNames、manualSingletonNames),后续实例化Bean、获取Bean时会用到
代码语言:javascript
复制
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");
		// 如果是AbstractBeanDefinition类型实例 进行validate
		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);
		// 首次进入 old为空
		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 {
		//首次为false
			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 {
				//仍处于启动注册阶段(即没有真正的实例化,只是将bean的属性定义拿到,还不可以直接使用。)
				
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}
SpringBean创建

在BeanDefiniton注入registry中后,一步步返回到 AbstractApplicationContext#refresh方法中,我们这里只关注基本的Bean实例化过程。

代码语言:javascript
复制
synchronized (this.startupShutdownMonitor) {
			try {
				
				// 主要是这个代码
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}
AbstractApplicationContext#finishBeanFactoryInitialization
  • org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

finishBeanFactoryInitialization。实例化BeanFactory持有的其他正常的非延迟加载的单例集合.。这里往下看“preInstantiateSingletons”方法

代码语言:javascript
复制
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//省略代码....

		// 实例化BeanFactory持有的其他正常的非延迟加载的单例集合
		beanFactory.preInstantiateSingletons();
	}
DefaultListableBeanFactory#preInstantiateSingletons

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons。创建Bean分为二种,一种是FactoryBean,一种是普通Bean。这里我们只分析普通Bean。

  • 注意这里的"this.beanDefinitionNames" 是“obtainFreshBeanFactory()”创建赋值的。即我们的StringUtils的BeanDefinition。
代码语言:javascript
复制
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					//我们重点关注的是这个地方哈
					getBean(beanName);
				}
			}
		}
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

继续跟进就行

代码语言:javascript
复制
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
(单例)org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

这里我们就是要创建单例的实例(有就从缓存中取)。创建的方式是通过ObjectFactory内部类实现中的createBean方法来完成。我们先看下getSingleton的逻辑。

代码语言:javascript
复制
		// 首次进来为空  最后会走下边的逻辑
		Object sharedInstance = getSingleton(beanName);
		// 通过this.beanDefinitionMap得到的  具体可自行查看源码。这里不太花篇幅讲述。
		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
		//...
		if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
							 	//最终创建Bean的逻辑
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
	//....		
	// 注意这里,会把单例cache起来,在后边可以直接使用
	if (newSingleton) {
		addSingleton(beanName, singletonObject);
	}
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

这里我们要分析的核心逻辑(instance singleton)是调用的了ObjectFactory.getObject,即我们上边的内部类,而内部类的实现则是通过createBean完成。我们再来看下createBean的逻辑。

代码语言:javascript
复制
			try {
					//回到了AbstractBeanFactory#doGetBean的ObjectFactory的getObject方法,执行其中的createBean方法
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

AbstractBeanFactory的子类实现方法

代码语言:javascript
复制
	AbstractAutowireCapableBeanFactory#createBean(java.lang.Class<T>)
	public <T> T createBean(Class<T> beanClass) throws BeansException {
		// Use prototype bean definition, to avoid registering bean as dependent bean.
		RootBeanDefinition bd = new RootBeanDefinition(beanClass);
		bd.setScope(SCOPE_PROTOTYPE);
		bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
		return (T) createBean(beanClass.getName(), bd, null);
	}

// 接上
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		
		RootBeanDefinition mbdToUse = mbd;
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			
		}
		// 普通Bean的实例创建
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
AbstractAutowireCapableBeanFactory#doCreateBean

核心关注instanceWrapper和exposedObject对象的处理过程

代码语言:javascript
复制
	BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建bean实例的Wrapper对象
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// bean实例在wrapper中已经创建了(不完整)
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		//省略一些代码。。。
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 注入property到Bean中
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		//省略一些代码。。。
		return exposedObject;
AbstractAutowireCapableBeanFactory#createBeanInstance

instanceWrapper = createBeanInstance(beanName, mbd, args); 该方法是给指定的name的Class创建Bean对象,支持无参、factoryMethod、AutoWireConstructor三种策略。默认执行无参的"instantiateBean"

代码语言:javascript
复制
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		// 一般我们不是FactoryMethod和有参构造(也可以有哈)
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		// Need to determine the constructor...
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		//没有特殊处理就使用无参构造实例
		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}
AbstractAutowireCapableBeanFactory#instantiateBean

通过“getInstantiationStrategy().instantiate(mbd, beanName, parent)”生成实例。

代码语言:javascript
复制
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				// 一般会走这块代码逻辑来生成bean实例
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}
SimpleInstantiationStrategy#instantiate

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)。 通过bd获取BeanDefinition中对应BeanName的Class构造方法实例,交给BeanUtils去实例化真正的bean对象

代码语言:javascript
复制
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (bd.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
								@Override
								public Constructor<?> run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							//获取xml中bean标签定义的Class的Constructor实例
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//实例化“xml中bean标签定义的Class”
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}
返回到 AbstractAutowireCapableBeanFactory#doCreateBean方法

我们继续看exposedObject处理的内容。装载Bean的Property属性,initBean对象。我们着重看下initializeBean方法。

代码语言:javascript
复制
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Object exposedObject = bean;
		try {
			//装载比如Property属性  可以是其他Bean对象,也可能是String等基本属性。  具体见populateBean中的applyPropertyValues方法
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				//初始化Bean对象
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
AbstractAutowireCapableBeanFactory#initializeBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

初始化给定的Bean,(RootBeanDefinition为空时,执行BeanPost)执行wired的相关方法((BeanNameAware、BeanClassLoaderAware、BeanFactoryAware))、执行initMethod。比如InitializingBean#afterPropertiesSet();或者是自定义的init方法。

代码语言:javascript
复制
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			//执行wire的method(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//执行init方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
AbstractAutowireCapableBeanFactory#invokeInitMethods

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods。执行afterPropertiesSet方法。如果是自定义的init方法,就调用invokeCustomInitMethod。

代码语言:javascript
复制
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}
返回 AbstractApplicationContext#refresh

至此Bean实例化完成。

代码语言:javascript
复制
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

SpringBean获取

还是我们的例子,在我们返回的ApplicationContext实例中,有个getBean方法,接下来我们着重来看getBean的实现。

代码语言:javascript
复制
 		//ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/spring/test.xml");
        context.getBean(StringUtils.class);
AbstractApplicationContext#getBean
代码语言:javascript
复制
	public <T> T getBean(Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType);
	}
DefaultListableBeanFactory#getBean(java.lang.Class<T>)

org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>) 。这里主要分析resolveNamedBean的源码逻辑。

代码语言:javascript
复制
	public <T> T getBean(Class<T> requiredType) throws BeansException {
		return getBean(requiredType, (Object[]) null);
	}
	
	@Override
	public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
		//获取NamedBeanHolder对象  核心获取SpringBean的逻辑
		NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
		if (namedBean != null) {
			//最后是这里返回实例
			return namedBean.getBeanInstance();
		}
		BeanFactory parent = getParentBeanFactory();
		if (parent != null) {
			return parent.getBean(requiredType, args);
		}
		throw new NoSuchBeanDefinitionException(requiredType);
	}
	//接上
DefaultListableBeanFactory#resolveNamedBean(java.lang.Class<T>, java.lang.Object...)

示例中的源码会执行"new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args))"。beanName=test.xml中定义的id,即"stringutil"。我们下边主要看下getBeanNamesForType和getBean方法的逻辑。

代码语言:javascript
复制
//requiredType= StringUtil  args=null
private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
		Assert.notNull(requiredType, "Required type must not be null");
		// 根据Class类型获取名字  示例中只有一个["stringutil"]
		String[] candidateNames = getBeanNamesForType(requiredType);

		if (candidateNames.length > 1) {
			List<String> autowireCandidates = new ArrayList<String>(candidateNames.length);
			for (String beanName : candidateNames) {
				if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
					autowireCandidates.add(beanName);
				}
			}
			if (!autowireCandidates.isEmpty()) {
				candidateNames = StringUtils.toStringArray(autowireCandidates);
			}
		}
		// 我们示例中length==1 ,beanName=stringutil  和我们定义的id保持一致
		if (candidateNames.length == 1) {
			String beanName = candidateNames[0];
			//注意看下getBean方法的执行逻辑
			return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
		}
		else if (candidateNames.length > 1) {
			Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length);
			for (String beanName : candidateNames) {
				if (containsSingleton(beanName)) {
					candidates.put(beanName, getBean(beanName, requiredType, args));
				}
				else {
					candidates.put(beanName, getType(beanName));
				}
			}
			String candidateName = determinePrimaryCandidate(candidates, requiredType);
			if (candidateName == null) {
				candidateName = determineHighestPriorityCandidate(candidates, requiredType);
			}
			if (candidateName != null) {
				Object beanInstance = candidates.get(candidateName);
				if (beanInstance instanceof Class) {
					beanInstance = getBean(candidateName, requiredType, args);
				}
				return new NamedBeanHolder<T>(candidateName, (T) beanInstance);
			}
			throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
		}

		return null;
	}
DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>)

最后是使用在解析xml时(loadBeanDefinition时),从存在this.beanDefinitionNames集合中获取beanName。具体看下边"doGetBeanNamesForType"方法的源码。

代码语言:javascript
复制
	public String[] getBeanNamesForType(Class<?> type) {
		return getBeanNamesForType(type, true, true);
	}
	// type==StringUtil 不为空
	public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
			return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
		}
		//cache为空 size==0
		Map<Class<?>, String[]> cache =
				(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
		String[] resolvedBeanNames = cache.get(type);
		if (resolvedBeanNames != null) {
			return resolvedBeanNames;
		}
		// 会执行这里!!!!
		resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
		if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
			cache.put(type, resolvedBeanNames);
		}
		return resolvedBeanNames;
	}
// 从this.beanDefinitionNames中获取beanName
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		List<String> result = new ArrayList<String>();

		// Check all bean definitions.
		for (String beanName : this.beanDefinitionNames) {
			// Only consider bean as eligible if the bean name
			// is not defined as alias for some other bean.
			if (!isAlias(beanName)) {
				try {
					RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					// Only check bean definition if it is complete.
					if (!mbd.isAbstract() && (allowEagerInit ||
							(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
									!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
						// In case of FactoryBean, match object created by FactoryBean.
						boolean isFactoryBean = isFactoryBean(beanName, mbd);
						BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
						boolean matchFound =
								(allowEagerInit || !isFactoryBean ||
										(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
								(includeNonSingletons ||
										(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
								isTypeMatch(beanName, type);
						if (!matchFound && isFactoryBean) {
							// In case of FactoryBean, try to match FactoryBean instance itself next.
							beanName = FACTORY_BEAN_PREFIX + beanName;
							matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
						}
						if (matchFound) {
							//最后会执行这里
							result.add(beanName);
						}
					}
				}
				catch (CannotLoadBeanClassException ex) {
					
				}
				catch (BeanDefinitionStoreException ex) {
					
				}
			}
		}

		

		return StringUtils.toStringArray(result);
	}
AbstractBeanFactory#getBean(String, Class<T>, Object...)

创建singleBean的过程请仔细看创建的代码,这里不讲述。

代码语言:javascript
复制
	public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
		return doGetBean(name, requiredType, args, false);
	}
	
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// 从缓存中获取。
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		//省略bean创建的代码
		return (T) bean;
	}
返回到DefaultListableBeanFactory#getBean的“namedBean.getBeanInstance()”方法中
代码语言:javascript
复制
		if (namedBean != null) {
			return namedBean.getBeanInstance();
		}
获取完成

最后返回到"context.getBean(StringUtils.class);",获取到Bean实例

代码语言:javascript
复制
StringUtils sutils=context.getBean(StringUtils.class);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring加载Bean、实例化Bean、获取Bean流程
    • Spring启动入口
      • 源码分析之Bean解析
        • 入口 ClassPathXmlApplicationContext
        • AbstractApplicationContext#refresh
        • SpringBean获取
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档