Spring源码学习之旅 初识IOC

初识IOC

作为Spring最最重要与核心的功能,我们需要先去了解Spring IOC是个什么东东,经过五个大版本的发展, Spring容器已经由早期的纯XML配置转为0XML配置,但是从XML来开始了解Spring IOC会让人更加的理解它的发展历程,那就从XML开始吧

什么是IOC

  • IOC,即 Inversion of Control,中文译名-控制反转,那么问题就来了,控制反转,反转的是什么控制?又是如何反转的?
  • 其实Spring最早的时候只干了一件事,就是将实例化的过程帮助程序员实现了,原本一个个需要由程序员来new的对象,不再需要自己在A类里new出B类的实例了。即原来的对象实例化,是交给程序员控制的,但是在spring里,对象的实例化这件事交给了spring容器来做,将控制权交给了spring,这个就叫控制反转
  • 那么如何把这件事交给spring做的呢,答案就是java的反射机制,当然中间的处理非常的繁琐,但是最核心的本质就是spring根据程序员提供的各类信息(xml配置、注解配置等)来控制类的实例化,避免程序员直接在A类中创建B类实例,造成代码的强耦合。

环境创建

请参见 《Spring源码学习之旅 先搞定环境再说!》

Spring.xml

这个最基础的xml定义了一个Spring的bean对象,定义了它的属性为id,class对象是谁,通过标签可以看到里面的属性特别的多,一起总结一下

<?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="hello" class="com.xiaoyingge.spring.bean.BeanXml"/>

</beans>

标签的定义,这里声明了与它对应的类是BeanDefinition,基本上一套看下来,Spring在内部定义了一个类BeanDefinition,将其属性与Spring的配置文件进行一一对应,因此这也为后续通过注解直接进行bean定义提供了可能。

<xsd:element name="bean">
		<xsd:annotation>
			<xsd:documentation source="java:org.springframework.beans.factory.config.BeanDefinition">xsd:documentation>
		xsd:annotation>
		<xsd:complexType>
			<xsd:complexContent>
				<xsd:extension base="identifiedType">
					<xsd:group ref="beanElements"/>
					<xsd:attributeGroup ref="beanAttributes"/>
				xsd:extension>
			xsd:complexContent>
		xsd:complexType>
	xsd:element>

重点要了解

  • BeanDefinition ------- 向spring容器描述用户对于每一个Bean的准确定义
  • BeanDefinitionRegister--------Spring中所有BeanDefinition的注册表,在ApplicationContext中体现为beanDefinitionMap
  • BeanDefinitionNames--------所有bean名称的注册表

BeanDefinition

BeanDefinition可以看到是一个接口,Spring通常通过它的实现类 RootBeanDefinition和GenericBeanDefinition来对bean的定义进行包装,下面看下它的属性是如何与xml 的标签进行对应的

XML标签名 BeanDefinition属性名 作用
id id bean 的唯一标识 ,容器唯一
name name bean 的别名,可以任意由字母数据符号组合
class beanClass 对应的类的全限定名,子类可以不定义
parent parentName 对应的类的全限定名
abstract abstract 定义抽象bean,抽象bean不会进行实例化,通常用作父bean,提供通用属性继承给子bean
lazy-init lazyInit 是否延迟加载,需要用到时才加载
autowired autowireMode 默认按类型type加载
no:不使用自动装配
byName:按bean名称装配
byType:按类型装配
constructor:按构造函数装配
autodetect:通过Bean的反省机制(introspection)
决定是按构造器装配还是按类型装配
depends-on dependsOn 依赖于谁,如果beanA中配置了dependsOn beanB,
那么在实例化beanA时会检查beanB有没有实例化,
如果B没有实例化,优先实例化beanB
init-method initMethodName 无参初始化方法,在bean实例化之后调用
destory-method destoryMethodName 无参销毁方法,在beanFactory销毁时调用,
applicationContext会触发上一个beanFactory的销毁运作
factory-method factoryMethodName 定义创建此类的工厂类,会导致class属性失效
autowire-candidate autowireCandidate
MutablePropertyValues propertyValues 设置bean对象的各个属性
ConstructorArgumentValues ConstructorArgumentValues 构造函数的属性
MethodOverrides setMethodOverrides 用于封装look-up method和replaced-method

从头开始

先看类的继承关系

重点关注下面几个类

  1. AbstractRefreshableConfigApplicationContext 持有配置文件路径属性,configLocations
  2. AbstractApplicationContext 定义了应用上下文的刷新模板方法
  3. ApplicationContext 应用上下文接口
  4. BeanFactory bean工厂接口

Spring源码学习之旅 初识IOC_第1张图片

IOC流程(一) 加载配置

ClassPathXmlApplicationContext()

这里是我们测试方法的入口 ,就从这里开始,从构造方法里一路调用,最终会到这里

	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		//父子容器使用,此处未用到,暂不分析
		super(parent);
		//设置配置文件的位置
		setConfigLocations(configLocations);
		if (refresh) {
			//刷新容器方法
			refresh();
		}
	}

AbstractRefreshableConfigApplicationContext.setConfigLocations()

先看setConfigLocations(configLocations);方法,它将配置文件的路径存放到父类的属性configLocations中

	public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				//将配置的文件路径存放到configLocations中
				this.configLocations[i] = resolvePath(locations[i]).trim();**
			}
		}
		else {
			this.configLocations = null;
		}
	}

AbstractApplicationContext.refresh()

再看重点方法refresh(),它会调用AbstractApplicationContext里的refresh()方法,这个方法使用了模板方法模式,在AbstractApplicationContext里定义好了Spring容器的加载顺序,将部分方法的实现细节交由各个子类进行了实现

@Override
	public void refresh() throws BeansException, IllegalStateException {
		//不管三七二十一,先加锁
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//销毁原有工厂,可以返回自定义的bean工厂,默认返回DefaultListableBeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//对bean工厂进行预处理,将一些spring需要使用的类先行实例化
			//比如 ApplicationContextAwareProcessor
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

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

				// Destroy already created singletons to avoid dangling resources.
				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();
			}
		}
	}

AbstractApplicationContext.obtainFreshBeanFactory()

本次我们主要看最简单的IOC过程是怎么实现的,因此其他的方法不在这里细看,主要看obtainFreshBeanFactory()方法

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//刷新bean工厂
		refreshBeanFactory();
		//返回刷新后的bean工厂
		return getBeanFactory();
	}

AbstractRefreshableApplicationContext.refreshBeanFactory()

refreshBeanFactory()又是一个抽象方法,ClassPathXmlApplicationContext的继承线上有一个AbstractRefreshableApplicationContext的抽象实现类里对它进行了重写,看下它的实现

@Override
	protected final void refreshBeanFactory() throws BeansException {
		//如果bean工厂已经存在
		if (hasBeanFactory()) {
			//删除所有单例bean
			destroyBeans();
			//销毁原有bean工厂
			closeBeanFactory();
		}
		try {
			//默认创建的bean工厂 DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//两个配置项
			//setAllowBeanDefinitionOverriding
			//      默认true,允许同名bean进行覆盖,后出现的bean会覆盖前面出现的同名bean
			//      如果设置为false,出现同名bean会报错提示
			//setAllowCircularReferences
			//      默认true,允许循环依赖,构造器依赖spring无法处理
			customizeBeanFactory(beanFactory);
			//加载XML里的bean配置
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

AbstractApplicationContext.loadBeanDefinitions()

此处未直接去加载相关的配置,而是将配置文件交给了一个XmlBeanDefinitionReader类去处理,这是根据单一职责的设计原则将不同的事情交给不同的类来处理,整个方法就是创建了一个reader,reader里持有了beanFactory的引用,reader去解析xml配置,将解析完的数据存放到beanFactory里

	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//创建一个beanXml解析器
		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);
		//加载bean定义
		loadBeanDefinitions(beanDefinitionReader);
	}

AbstractApplicationContext.loadBeanDefinitions()

这是一个overwrite方法,只干了一件事,获取已知的 文件路径,按路径进行解析

	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		//获得刚才传入的配置文件地址configLocations
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

AbstarctBeanDefinitionReader.loadBeanDefinitions()

循环已知路径,进行解析,最终会交给对应的XmlBeanDefinitionReader来处理

	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");
		int count = 0;
		for (String location : locations) {
			//遍历路径 ,读取配置文件
			count += loadBeanDefinitions(location);
		}
		return count;
	}

XmlBeanDefinitionReader.loadBeanDefinitions()

这里将文件读取为文件流,进行格式转码等前置操作,将其扔给doLoadBeanDefinitions()里进行执行,在Spring的源码里有个特点 ,叫doXXX()的方法通常都是真正去做业务处理的方法, 这点后面可以留意

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);
		}

		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		//按路径将文件读取为输入流
		try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
			InputSource inputSource = new InputSource(inputStream);
			if (encodedResource.getEncoding() != null) {
				inputSource.setEncoding(encodedResource.getEncoding());
			}
			//真正的解析方法
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}

XmlBeanDefinitionReader.doLoadBeanDefinitions()

将流对象包装为一个Document对象,扔到registerBeanDefinitions()里处理

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			//获取配置的doc文档
			Document doc = doLoadDocument(inputSource, resource);
			//根据doc文档内容注册beanDefinition
			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);
		}
	}

XmlBeanDefinitionReader.registerBeanDefinitions()

创建一个文档阅读器,将上一步生成的文档传给文档阅读器进行解析,解析完成后将beanDefinition对象注册,并返回本次让beanDenition对象产生了多少数量的变化

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//创建文档阅读器
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//注册前的beanDefinition数量
		int countBefore = getRegistry().getBeanDefinitionCount();
		//注册beanDefinition
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//返回数量变化
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions()

这个类本身是一个文档阅读器,因此spring在设计中,这个类的功能就是解析文档内容,因此注册BeanDefinition对象的事件,它交给了一个委托对象,由BeanDefinitionParserDelegate来处理注册相关的事情

protected void doRegisterBeanDefinitions(Element root) {
		// Any nested  elements will cause recursion in this method. In
		// order to propagate and preserve  default-* attributes correctly,
		// keep track of the current (parent) delegate, which may be null. Create
		// the new (child) delegate with a reference to the parent for fallback purposes,
		// then ultimately reset this.delegate back to its original (parent) reference.
		// this behavior emulates a stack of delegates without actually necessitating one.
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);

		if (this.delegate.isDefaultNamespace(root)) {
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				// We cannot use Profiles.of(...) since profile expressions are not supported
				// in XML config. See SPR-12458 for details.
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}
		//模板方法
		preProcessXml(root);
		//解析bean定义并进行注册 
		parseBeanDefinitions(root, this.delegate);
		//模板方法,spring里这种前后置的模板方法运用的非常多
		postProcessXml(root);

		this.delegate = parent;
	}

DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()

解析对应的元素

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 {
			//解析自定义元素,这个方法应该是由解析如import类的文件使用
			delegate.parseCustomElement(root);
		}
	}

DefaultBeanDefinitionDocumentReader.parseDefaultElement()

对默认支持的bean import 等XML标签进行解析

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			//解析import进来的文件
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			//处理别名注册
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			//解析beanDefinition的定义
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// 进行嵌套对象的解析
			doRegisterBeanDefinitions(ele);
		}
	}

DefaultBeanDefinitionDocumentReader.processBeanDefinition()

这里会将文档内的定义,每一个包装成一个BeanDefinition对象,再由一个BeanDefinitionHolder来包装,具体的解析细节后面会单独抽一章来写,此处不做扩展

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//将解析完的XML文档包装到一个BeanDefinitionHolder中
		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));
		}
	}

BeanDefinitionReaderUtils.registerBeanDefinition()

最终进行BeanDefinition与别名的注册

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//注册beanDefinition对象
		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);
			}
		}
	}

IOC流程(二)初始化

到上面,一个简单的BeanDefinition对象就已经加载完成了,那么这个定义在什么时候被Spring使用了呢?回到AbstractApplicationContext的refresh()方法中,看下

@Override
	public void refresh() throws BeansException, IllegalStateException {
	    ....
	    // Instantiate all remaining (non-lazy-init) singletons.
	    //初始化非懒加载的单例bean
        finishBeanFactoryInitialization(beanFactory);
        ....

AbstractApplicationContext.finishBeanFactoryInitialization()

重点关注最后的一个方法 beanFactory.preInstantiateSingletons();

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//单懒加载的单例bean开始实例化
		beanFactory.preInstantiateSingletons();
	}

DefaultListableBeanFactory.preInstantiateSingletons()

在这里规定了,抽象的,非单例的,懒加载的bean本次不会处理
对于beanFactory对象前面加上&就可以拿到bean的工厂对象,也是在源码里写死的,下面的注释里可以看到,后续会知道,@Bean就是通过beanFactory的方式来创建Bean实例的,这里不多做解释
getBean()方法会调用doGetBean()方法,执行bean获取逻辑

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		//之前扫描的beanNames进行循环
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//合并父子对象 即带有parent标签的对象
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//只有非抽象,单例,非懒加载的对象进行实例化逻辑
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//工厂bean创建
				if (isFactoryBean(beanName)) {
					//前端加上&号就可以拿到FactoryBean的实例,即加工指定Bean的工厂bean
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							//需要提前实例化的对象
							getBean(beanName);
						}
					}
				}
				else {
					//非工厂bean的实例化路线
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

AbstractBeanFactory.doGetBean()

这里的方法非常多,重点看几个,
一是在入口处调用了 Object sharedInstance = getSingleton(beanName);从缓存内拿到已经实例化过的对象,保证单例,并且在这里使用了三级缓存,解决了单例循环依赖问题(需要注意的是,构造方法式的依赖注入,无法通过三级缓存解决)
二是解决了dependsOn优先实例化被依赖对象的问题
三是根据BeanDefinition的描述,创建各类bean对象
这里我们重点看单例bean实例化的方法 createBean(beanName, mbd, args);

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

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

		// Eagerly check singleton cache for manually registered singletons.
		//从缓存里获取bean对象,也是在这里解决了循环依赖问题
		Object sharedInstance = getSingleton(beanName);
		
		....省略部分代码


		//如果Prototype类型出现的循环引用,直接抛出异常
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		....省略部分代码
				
		String[] dependsOn = mbd.getDependsOn();
		if (dependsOn != null) {
			for (String dep : dependsOn) {
				....省略部分代码
				//注册被依赖的bean
				registerDependentBean(dep, beanName);
				try {
				//优先获取依赖的bean
					getBean(dep);
				}
				....省略部分代码

				// 创建单例bean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//单例bean创建
							return createBean(beanName, mbd, args);
						}
						....省略部分代码
				
					//Prototype类型bean创建
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						//Prototype类型bean创建
						prototypeInstance = createBean(beanName, mbd, args);
					}
					....省略部分代码
		return (T) bean;
	}

AbstractAutowireCapableBeanFactory.createBean()

这里有几点
一是处理了MethodOverride方法
二是提供了一个创建bean对象代理类的入口 ,AOP的动态代理就是在这里创建的
调用doCreateBean(beanName, mbdToUse, args);方法创建bean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			//创建一个RootBeanDefinition
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//给实例一个返回代理对象的机会 ,AOP创建动态代理就是走的这里
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//创建bean对象
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

AbstractAutowireCapableBeanFactory.doCreateBean()

这里调用了createBeanInstance创建bean实例

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建bean实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		....省略部分代码
	}

AbstractAutowireCapableBeanFactory.createBeanInstance()

无参实例化调用 instantiateBean方法

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		...省略部分代码
		// No special handling: simply use no-arg constructor.
		//常规的无参实例化
		return instantiateBean(beanName, mbd);
	}

AbstractAutowireCapableBeanFactory.instantiateBean()

无参实例化调用 instantiateBean方法

try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				//获取实例化策略进行实例化
				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()

调用BeanUtils.instantiateClass(constructorToUse)进行实例化

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (!bd.hasMethodOverrides()) {
			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(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//实例化bean对象
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

BeanUtils.instantiateClass()

终于走到newInstance了,对了,可以放心大胆的说IOC是通过反射来完成的了,它就是用的反射!

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			//设置反射的构造器
			ReflectionUtils.makeAccessible(ctor);
			//kotlin的支持
			if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
				return KotlinDelegate.instantiateClass(ctor, args);
			}
			else {
				Class<?>[] parameterTypes = ctor.getParameterTypes();
				Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
				Object[] argsWithDefaultValues = new Object[args.length];
				for (int i = 0 ; i < args.length; i++) {
					if (args[i] == null) {
						Class<?> parameterType = parameterTypes[i];
						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
					}
					else {
						argsWithDefaultValues[i] = args[i];
					}
				}
				//创建对应实例,并将前面解析的参数装载进去
				return ctor.newInstance(argsWithDefaultValues);
			}
		}
		catch (InstantiationException ex) {
			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
		}
		catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
		}
		catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
		}
		catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
		}

总结

其实这将近三万字的代码里 只是做了最简单的反射实例化,像循环依赖的解决,生命周期函数的调用等等都没有涉及到,这里简单的走一遍只是为了建立一个概念,即Spring的IOC本质上只干两件事

一、解析你给的配置信息,无论它是XML的也好,还是注解的也好,最终会将你对bean以及bean关系的描述包装为一个BeanDefinition注册到BeanDefinitionRegisity中
二、根据你的BeanDefinitionRegisity中注册的相关BeanDefinition描述,按你的要求将所有的Bean实例化出来,并将对应的内容注入到对象中(本章未追相关代码)

你可能感兴趣的:(#,Spring)