Spring IOC源码解析

前言

说到Spring,似乎IOC、DI成为了我们的共鸣。工作中,Spring无处不在,如影随形,Spring给我们开发者带来了一个春天。这么优秀而美丽的框架,我想,源码是值得我们去深入学习的。

入口准备

我使用的是spring-framework5.0.x版本,新建一个模块,作为自己的代码编写使用,需要在项目中已有的build.gradle文件引入一些配置和依赖,如下

plugins {
    id 'java'
}
group 'org.springframework'
version '5.0.16.BUILD-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    //引入本次所需依赖模块 context模块包括了beans、aop、core、expression等
    compile(project(":spring-context"))
}
//如果新建的模块没有java及resources使用如下进行创建
task 'create-dirs' {
    doLast {
        sourceSets*.java.srcDirs*.each {
            it.mkdirs()
        }
        sourceSets*.resources.srcDirs*.each {
            it.mkdirs()
        }
    }
}

appliationContent.xml

<bean id="messageService" name="m1,m2,m3" class="com.whp.service.impl.MessageServiceImpl">
        <!--引入下面id为message的bean-->
		<property name="message" ref="message"/>
	</bean>
	<bean id="message" class="com.whp.bean.Message"/>

Message.java

/**
 * @author wanghp
 * @version 1.0
 * @date 2020/7/8 23:19
 */

public class Message {
	public Message() {
		//待会MessageServiceImpl注入Message会打印
		System.out.println("instance Message Bean");
	}
}

MessageServiceImpl.java

/**
 * @author wanghp
 * @version 1.0
 * @date 2020/7/8 23:41
 */
public class MessageServiceImpl implements MessageService, BeanNameAware {

	private Message message;

	public MessageServiceImpl() {
		//实例化MessageServiceImpl Bean会打印
		System.out.println(" instance MessageServiceImpl Bean");
	}

	public void setMessage(Message message) {
		this.message = message;
	}
	
	@Override
	public String speak() {
		System.out.println(message);
		return "this is my test -->spring ioc ";
	}
    //BeanNameAware回调方法,其实还有BeanClassLoaderAware、BeanFactoryAware
	@Override
	public void setBeanName(String name) {
		System.out.println("BeanNameAware:" + name);
	}
}

Junit Test 也就是我们学习源码的入口,对于学习Spring找到一个入口是非常重要的。

	@Test
	public void XMLTest() {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("appliationContent.xml");
		MessageService messageService = (MessageService) applicationContext.getBean("messageService");
		System.out.println(messageService.speak());
	}

这是我新建测试的gradle模块列表结构
在这里插入图片描述
在进入ClassPathXmlApplicationContext构造方法之前,一般我们学习源码常用的2种方式,如下
在这里插入图片描述
1.ClassPathXmlApplicationContext:见名知意,基于类路径下的xml作为Spring容器初始化
2.AnnotationConfigApplicationContext:类似于SpringBoot启动加载,将主类传入构造方法。
这两种里面其实都是围绕refresh()里的13个方法展开的,本次我们使用第一种,基于xml的方式。

启动过程分析

	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
        super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			//因为 ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建的,
			// refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。
			refresh();
		}
	}

进入refresh()方法,先对里面的13个方法有个大概的印象。

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		//来个锁,不然你refresh()方法还没结束,你又来个启动或销毁的操作,岂不是乱套了?????
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
			// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
			// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
			// 这块待会会展开说
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
				// 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】

				// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
				// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
				// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
				// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 从方法名就可以知道,典型的模板方法(钩子方法),
				// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
				onRefresh();

				// Check for listener beans and register them.
				// 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有的 singleton beans
				//(lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后,广播事件,ApplicationContext 初始化完成
				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.
				// 销毁已经初始化的 singleton 的 Beans,以免有些 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();
			}
		}
	}
初始化准备工作

主要还是校验xml,设置一些初始化值…

	protected void prepareRefresh() {
		// 记录启动时间,
		// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 校验 xml 配置文件
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		} else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
		
		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
解析xml,注册bean,初始化BeanFactory
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
		refreshBeanFactory();
		// 返回刚刚创建的 BeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
		@Override
	protected final void refreshBeanFactory() throws BeansException {
		// 如果 ApplicationContext 中已经加载过 BeanFactory 了,销毁所有 Bean,关闭 BeanFactory
		// 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
		// ApplicationContext 是否有 BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 初始化一个 DefaultListableBeanFactory,为什么用这个,我们马上说。
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 用于 BeanFactory 的序列化,我想不部分人应该都用不到
			beanFactory.setSerializationId(getId());

			// 下面这两个方法很重要,别跟丢了,具体细节之后说
			// 1.设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
			customizeBeanFactory(beanFactory);

			//2.加载 Bean 到 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);
		}
	}

到了loadBeanDefinitions方法,他传入了个beanFactory,通过方法名,我们可以大概猜测到这个是加载BeanDefinition的,还是多个BeanDefinition,然后可能是放到beanFactory里。
对于BeanFactory也就是Bean工厂和这里的实现类DefaultListableBeanFactory肯定是有联系的,我们先来看一下这两者的UML图:
在这里插入图片描述
DefaultListableBeanFactory:由图我们可以发现,它几乎拥有了上面所有的能力,它的顶层几乎要么是接口,要么是抽象类,而对于DefaultListableBeanFactory而言,它就是一个实现类,拥有了顶层所有的能力,这也就是为什么DefaultListableBeanFactory是整个spring ioc的始祖,研究透它的前生今世对我们理解spring ioc的概念有着重要的作用。
BeanFactory:没什么好讲的,大致理解为Bean工厂吧,里面的一些方法无非就是通过各种传参类型获取Bean。
BeanDefinitionRegistry:如果一个类是BeanFactory的实现类,那么它就需要实现BeanDefinitionRegistry接口,原因很简单,Bean工厂需要个人帮他把外部的比如xml配置的,或者基于注解扫面的bean注册到Bean工厂,每个角色都有自己的职责,而不是BeanFactory什么都去做,体现了接口与的单一职责设计原则。

Q:到这里,那么会有一个面试题,BeanFactory和FactoryBean的区别?
A:先看个FactoryBean的几个实现类,相信你差不多知道答案了,
在这里插入图片描述
FactoryBean其实可以理解为Spring的一种灵活的应用,先看个简单案例:

xml:
<bean id="person" class="com.whp.service.impl.PersonFactoryBean">
				<property name="personInfo" value="wanghp,100"/>
</bean>

PersonFactoryBean.java  
public class PersonFactoryBean implements FactoryBean<Person> {
	protected final Log logger = LogFactory.getLog(getClass());

	private String personInfo;

	public String getPersonInfo() {
		return personInfo;
	}

	public void setPersonInfo(String personInfo) {
		this.personInfo = personInfo;
	}

	@Override
	public Person getObject() throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("进入getObject");
		}
		logger.info("进入getObject");
		Person person = new Person();
		String[] split = personInfo.split(",");
		person.setName(split[0]);
		person.setAge(Integer.parseInt(split[1]));
		return person;
	}

	@Override
	public Class<?> getObjectType() {
		logger.info("进入getObjectType");
		return Person.class;
	}
}
测试:
	@org.junit.Test
	public void FactoryBeanTest() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("appliationContent.xml");
		Object person = applicationContext.getBean("&person");
		System.out.println(person);//结果输出:com.whp.service.impl.PersonFactoryBean@88af592
		Object personBean = applicationContext.getBean("person");//结果输出:com.whp.bean.Person@241ac1a4
		System.out.println(personBean);
		((Person) personBean).message();
		//在Person类输出属性信息为:wanghp今年100岁啦
	}

如果你在PersonFactoryBean的getObject方法,比如我把设置年龄改成person.setAge(3);
sout为:wanghp今年3岁啦 当然我也不可能3岁哈哈,题外话
所以一个FactoryBean和你想要的普通Bean就是一念之间("&"),如果想具体了解这两者区别,小伙伴们可以自行查阅相关资料,我们回归正轨…

下面开始进入验证阶段。

AbstractXmlApplicationContext.java

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

上面无非就是设置beanDefinitionReader的环境,加载资源,实体分解器EntityResolver,有个概念为SAX,你就把它当作是一个将xml解析到javaBean的东西,进入loadBeanDefinitions方法

	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			//这里不会进来,因为getConfigResources()就是返回Null
			reader.loadBeanDefinitions(configResources);
		}
		//这个就是拿到我们前面ClassPathXmlApplicationContext构造传进来的xml文件名
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			//走这里
			reader.loadBeanDefinitions(configLocations);
		}
	}

进入loadBeanDefinitions方法

	@Override
	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");
		int counter = 0;
		// 注意这里是个 for 循环,也就是每个文件是一个 resource
		for (String location : locations) {
			counter += loadBeanDefinitions(location);
		}
		// 最后返回 counter,表示总共加载了多少的 BeanDefinition
		return counter;
	}

再进入loadBeanDefinitions方法,下面这段代码是不是头皮发麻了,看我标记todo 那2行,前面通过
location也就是字符串"appliationContent.xml",把xml加载进来编程一个Resource,因为配置文件能传多个,所以是个数组,然后将其传到loadBeanDefinitions进行解析

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

		if (resourceLoader instanceof ResourcePatternResolver) {
			// Resource pattern matching available.
			try {
			  //todo 核心部分在这里
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources);
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
				}
				return loadCount;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// Can only load single resources by absolute URL.
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
			}
			return loadCount;
		}
	}

进入loadBeanDefinitions方法

	@Override
	public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		Assert.notNull(resources, "Resource array must not be null");
		int counter = 0;
		for (Resource resource : resources) {
			//看这里
			counter += loadBeanDefinitions(resource);
		}
		return counter;
	}

再进去,然后到了这里,因为我们解析是xml,所以这个方法所在类为XmlBeanDefinitionReader
将传进来的resource构造放入EncodedResource,然后拿到InputStream二进制流,将其封装为一个InputSource对象,然后丢到doLoadBeanDefinitions方法,resource通过get又回到了原来姿态

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);
		}
        // 用一个 ThreadLocal 来存放配置文件资源
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		System.out.println(Thread.currentThread().getName());
		if (currentResources == null) {
			currentResources = new HashSet<>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		System.out.println("now threadName :"+Thread.currentThread().getName());
		if (!currentResources.add(encodedResource)) {
			System.out.println("insert if----"+Thread.currentThread().getName());
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		System.out.println("out if ----"+Thread.currentThread().getName());
		try {
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				// 核心部分是这里,往下面看
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			} finally {
				inputStream.close();
			}
		} catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		} finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}

进入doLoadBeanDefinitions

	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		  //此处省略try{}catch代码
			// 这里就不看了,将 xml 文件转换为 Document 对象
			Document doc = doLoadDocument(inputSource, resource);
			//TODO 解析及注册 BeanDefinition
			return registerBeanDefinitions(doc, resource);

进入registerBeanDefinitions,原来的inputSource变为了Document,而resource还是原来的配方

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	//TODO 单一职责原则,DefaultDocumentLoader执行得到doc,而这个BeanDefinitionDocumentReader就是逻辑处理类
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//todo 注册该xml前Bean 的数量
		int countBefore = getRegistry().getBeanDefinitionCount();
		//todo 加载及注册Bean
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//todo 记录本次加载的 BeanDefinition 个数
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

继续进入registerBeanDefinitions

	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		// 前面都是XML解析的准备阶段
		// 核心部分开始
		// 从 xml 根节点开始解析文件
		doRegisterBeanDefinitions(root);
	}

到这里,核心解析xml部分来了哈,进入doRegisterBeanDefinitions方法,传入的是Element

	protected void doRegisterBeanDefinitions(Element root) {
		BeanDefinitionParserDelegate parent = this.delegate;
		//TODO 委托给delegate解析    
		this.delegate = createDelegate(getReaderContext(), root, parent);
		//判断当前Beans节点是否是默认命名空间
		if (this.delegate.isDefaultNamespace(root)) {
			// 这块说的是根节点 <beans ... profile="dev" /> 中的 profile 是否是当前环境需要的,
			// 如果当前环境配置的 profile 不包含此 profile,那就直接 return 了,不对此 <beans /> 解析
		
			//获取beans节点的profile属性       "profile"
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				//可以使用逗号或分号将当前beans标签指定为多个profile类型
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				//判断当前beans标签的profile是否被激活
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isInfoEnabled()) {
						logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}
		//解析前处理,留给子类实现
		//pre和post里面目前没有具体实现,模板设计模式,一个类要么面向继承设计,要么就用final修饰
		preProcessXml(root);
		//看这里
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);
		this.delegate = parent;
	}

进入parseBeanDefinitions方法,主要就是Element和Node一些转换,判断,目前我们xml是默认标签配置的,也就是bean开头,当然你也可以自定义配置,这需要去写自己的schemas及xsd

	 // default namespace 涉及到的就四个标签 <import />、<alias />、<bean /> 和 <beans />,
    // 其他的属于 custom 的
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//TODO 对bean
		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方法,就到了我们解析标签了,判断默认标签属于什么类型,找到对应解析方法,我们目前是解析标签的

	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			//解析import标签
			importBeanDefinitionResource(ele);
		} else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			//解析alias标签
			processAliasRegistration(ele);
		} else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			//解析bean标签   看这里
			processBeanDefinition(ele, delegate);
		} else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

进入解析bean的对应方法,重点来了哈,各位提提精神…
到这里,才是真正的解析单个bean标签,变为一个javaBean,也就是我们这里的bdHolder,然后调用registerBeanDefinition注测我们的BeanDefinition,后面我们大概会讲一下这些概念,帮小伙伴们梳理一下这块内容

	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		// 将 <bean /> 节点转换为 BeanDefinitionHolder,就是上面说的一堆
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		//TODO 终于出来了,纪念一下当前时间 2020-05-19 15:27
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 将bdHolder注册到bean工厂
				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));
		}
	}

先看如何将一个标签内容变为BeanDefinitionHolder,进入parseBeanDefinitionElement方法,他这里使用的是BeanDefinitionParserDelegate解析器

	 	@Nullable
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		//解析 id属性
		String id = ele.getAttribute(ID_ATTRIBUTE);
		//解析 name属性
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		//分割 name属性
		List<String> aliases = new ArrayList<>();
		// 将 name 属性的定义按照 “逗号、分号、空格” 切分,形成一个 别名列表数组,
		// 当然,如果你不定义 name 属性的话,就是空的了
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		String beanName = id;
		// 如果没有指定id, 那么用别名列表的第一个名字作为beanName
		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);
		}
		// 根据 <bean ...>...</bean> 中的配置创建 BeanDefinition,然后把配置中的信息都设置到实例中,
		// 细节后面细说,先知道下面这行结束后,一个 BeanDefinition 实例就出来了。
		// 注意: 是一个 !!!!!!!!!!!!!!!!
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		// 到这里,整个 <bean /> 标签就算解析结束了,一个 BeanDefinition 就形成了。
		if (beanDefinition != null) {
			// 如果都没有设置 id 和 name,那么此时的 beanName 就会为 null,进入下面这块代码产生
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) { // 按照我们的思路,这里 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)) {
							// 把 beanClassName 设置为 Bean 的别名
							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;
	}         

上面看注释就好,然后核心方法是parseBeanDefinitionElement,返回AbstractBeanDefinition的对象,先讲讲AbstractBeanDefinition,UML如下
在这里插入图片描述
至于这几个类的用法小伙伴们可以自行百度,网上这些类说明及注释很全面,只需要记住AbstractBeanDefinition是个抽象类,提供相对比较全面的属性,然后下面是常用的3个实现类。

进入parseBeanDefinitionElement方法,主要就是解析标签的一些属性放入到BeanDefinition中,bean标签没有的会采用默认的值,比如scope=“singleton”

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

		this.parseState.push(new BeanEntry(beanName));
		//解析class属性
		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		String parent = null;
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
			//创建用于承载属性的 AbstractBeanDefinition 类型的 GenericBeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//硬编码解析默认 bean 的各种属性
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			/**
			 * 下面的一堆是解析 <bean>......</bean> 内部的子元素,
			 * 解析出来以后的信息都放到 bd 的属性中
			 */

			//解析元数据
			parseMetaElements(ele, bd);
			//解析 lookup-method 属性
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			//解析 replaced-method 属性
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

			//总结:无论look-up replaced-method都是构造了一个MethodOverride,
			// 并最终记录在了AbstractBeanDefinition的methodOverrides属性中
			//解析构造函数参数
			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;
	}

总结一下parseBeanDefinitionElement方法如何产生BeanDefinitionHolder对象的
1.AbstractBeanDefinition:解析bean标签完了将标签属性封装在一个(也就是bd)
2.beanName:beanName只有一个,别名可以有多个,两者都是关联起来的。
3.aliasesArray:别名集合,对应bean标签的name属性
然后将1,2,3构造封装在BeanDefinitionHolder

注册BeanDefinition

进入 BeanDefinitionReaderUtils 的registerBeanDefinition方法

	/**
	 * 从下面面的代码可以看出,解析的 beanDefinition 都会被注册到 ,
	 * BeanDefinitionRegistry 类型的实例 registry 中,而对于 beanDefinition
	 * 的注册分成了两部分:通过 beanName 的注册以及通过别名的注册。
	 */
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		//使用 beanName 做唯一标识注册
		String beanName = definitionHolder.getBeanName();
		//1.通过 beanName 注册 BeanDefinition
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//2.注册所有的别名
		// 如果还有别名的话,也要根据别名全部注册一遍,不然根据别名就会找不到 Bean 了
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

看看如何将BeanDefinitionHolderBeanDefinition 注册吧,其实这部分看起来比较常,正常逻辑会走else的this.beanDefinitionMap.put(beanName, beanDefinition);这行代码,看到这里,就知道前面为什么会返回一个DefaultListableBeanFactory的bean工厂了吧,所以最后注册BeanDefinition是在Bean的始祖DefaultListableBeanFactory里面注册的,应证了我们最初的结论,这其实就是个推导到论证的过程。这部分目前只是单个bean注册到bean工厂的beanDefinitionMap过程。

	@Override
	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 {
				//注册前的最后一次校验,这里的校验不同于之前的XML校验,
				// 但是此校验非彼校验,之前的校验时针对于 XML 格式的校验,而此时的校验时针是对于 AbstractBean- Definition 的 methodOverrides 属性的。
				//要是对于 AbstractBeanDefinition 属性中的**
				//校验 methodOverrides 是否与工厂方法并存或者**
				((AbstractBeanDefinition) beanDefinition).validate();
			} catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		//因为 beanDefinitionMap 是全局变量,这里定会存在并发访问
		// old? 还记得 “允许 bean 覆盖” 这个配置吗?allowBeanDefinitionOverriding
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		// 处理重复名称的 Bean 定义的情况
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				// 如果不允许覆盖的话,抛异常
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
								"': There is already [" + existingDefinition + "] bound.");
			} else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				// log...用框架定义的 Bean 覆盖用户自定义的 Bean
				if (logger.isWarnEnabled()) {
					logger.warn("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			} else if (!beanDefinition.equals(existingDefinition)) {
				//用新的 Bean 覆盖旧的 Bean
				if (logger.isInfoEnabled()) {
					logger.info("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			} else {
				//	用同等的 Bean 覆盖旧的 Bean,这里指的是 equals 方法返回 true 的 Bean
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			//覆盖
			this.beanDefinitionMap.put(beanName, beanDefinition);
		} else {
			// 判断是否已经有其他的 Bean 开始初始化了.
			// 注意,"注册Bean" 这个动作结束,Bean 依然还没有初始化,我们后面会有大篇幅说初始化过程,
			// 在 Spring 容器启动的最后,会 预初始化 所有的 singleton beans
			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<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			} else {
				// 最正常的应该是进到这个分支。
				// Still in startup registration phase
				// 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition
				this.beanDefinitionMap.put(beanName, beanDefinition);
				// 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字
				this.beanDefinitionNames.add(beanName);
				// 这是个 LinkedHashSet,代表的是手动注册的 singleton bean,
				// 注意这里是 remove 方法,到这里的 Bean 当然不是手动注册的
				// 手动指的是通过调用以下方法注册的 bean :
				//     registerSingleton(String beanName, Object singletonObject)
				// 这不是重点,解释只是为了不让大家疑惑。Spring 会在后面"手动"注册一些 Bean,
				// 如 "environment"、"systemProperties" 等 bean,我们自己也可以在运行时注册 Bean 到容器中的
				this.manualSingletonNames.remove(beanName);
			}
			// 这个不重要,在预初始化的时候会用到,不必管它。
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			//TODO 重置所有的beanName对应的缓存
			resetBeanDefinition(beanName);
		}
	}

不知道到了这里,还有多少小伙伴在坚持呢?
上面无非就是加载配置文件读标签然后将标签内容放入到BeanDefinition中,然后注册到beanFactory的beanDefinitionMap,说到这个注册,小伙伴千万别搞懵了,这里注册的是BeanDefinition,还不是我们平常用的Spring管理的Bean,对于BeanDefinition,他只是一个暂时存储bean标签信息,如果这个bean是单例还是多例,是懒加载还是非拦截在,看下面代码就明白了

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	// 我们可以看到,默认只提供 sington 和 prototype 两种,
	// 很多读者可能知道还有 request, session, globalSession, application, websocket 这几种,
	// 不过,它们属于基于 web 的扩展。
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

	int ROLE_APPLICATION = 0;

	int ROLE_SUPPORT = 1;

	int ROLE_INFRASTRUCTURE = 2;

	// 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。请参见附录的详细介绍
	// 一句话就是:继承父 Bean 的配置信息而已
	void setParentName(@Nullable String parentName);

	// 获取父 Bean
	@Nullable
	String getParentName();

	//设置 Bean的类名称,将来是要通过反射来生成实例的
	void setBeanClassName(@Nullable String beanClassName);

	// 获取 Bean 的类名称
	@Nullable
	String getBeanClassName();

	// 设置 bean 的 scope
	void setScope(@Nullable String scope);

	@Nullable
	String getScope();

	// 设置是否懒加载
	void setLazyInit(boolean lazyInit);

	boolean isLazyInit();

	// 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
	// 是 depends-on="" 属性设置的值。
	void setDependsOn(@Nullable String... dependsOn);

	// 返回该 Bean 的所有依赖
	@Nullable
	String[] getDependsOn();

	// 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
	// 如果根据名称注入,即使这边设置了 false,也是可以的
	void setAutowireCandidate(boolean autowireCandidate);

	// 该 Bean 是否可以注入到其他 Bean 中
	boolean isAutowireCandidate();
	// 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
	void setPrimary(boolean primary);

	// 是否是 primary 的
	boolean isPrimary();

	// 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
	// 一句话就是:有些实例不是用反射生成的,而是用工厂模式生成的
	void setFactoryBeanName(@Nullable String factoryBeanName);

	// 获取工厂名称
	@Nullable
	String getFactoryBeanName();

	// 指定工厂类中的 工厂方法名称
	void setFactoryMethodName(@Nullable String factoryMethodName);

	// 获取工厂类中的 工厂方法名称
	@Nullable
	String getFactoryMethodName();

	// 构造器参数
	ConstructorArgumentValues getConstructorArgumentValues();

	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}

	// Bean 中的属性值,后面给 bean 注入属性值的时候会说到
	MutablePropertyValues getPropertyValues();


	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

	// 是否 singleton
	boolean isSingleton();

	// 是否 prototype
	boolean isPrototype();


	// 如果这个 Bean 是被设置为 abstract,那么不能实例化,
	// 常用于作为 父bean 用于继承,其实也很少用......
	boolean isAbstract();

	int getRole();

	@Nullable
	String getDescription();

	@Nullable
	String getResourceDescription();

	@Nullable
	BeanDefinition getOriginatingBeanDefinition();

}
准备BeanFactory

这断你可以理解为前面beanFactory不是拿到了,这里是填充一下其他的东西,把要的放进来,不要的忽视就ok了,具体看注释

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 设置 BeanFactory 的类加载器,我们知道 BeanFactory 需要加载类,也就需要类加载器,
		// 这里设置为加载当前 ApplicationContext 类的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置 BeanExpressionResolver
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加一个 BeanPostProcessor,这个 processor 比较简单:
		// 实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调,
		// 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
		// 注意:它不仅仅回调 ApplicationContextAware,
		//   还会负责回调 EnvironmentAware、ResourceLoaderAware 等,看下源码就清楚了
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

		// 下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,
		// Spring 会通过其他方式来处理这些依赖。
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		/**
		 * 下面几行就是为特殊的几个 bean 赋值,如果有 bean 依赖了以下几个,会注入这边相应的值,
		 * 之前我们说过,"当前 ApplicationContext 持有一个 BeanFactory",这里解释了第一行。
		 * ApplicationContext 还继承了 ResourceLoader、ApplicationEventPublisher、MessageSource
		 * 所以对于这几个依赖,可以赋值为 this,注意 this 是一个 ApplicationContext
		 * 那这里怎么没看到为 MessageSource 赋值呢?那是因为 MessageSource 被注册成为了一个普通的 bean
		 */
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 这个 BeanPostProcessor 也很简单,在 bean 实例化后,如果是 ApplicationListener 的子类,
		// 那么将其添加到 listener 列表中,可以理解成:注册 事件监听器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 这里涉及到特殊的 bean,名为:loadTimeWeaver,这不是我们的重点,忽略它
		// tips: ltw 是 AspectJ 的概念,指的是在运行期进行织入,这个和 Spring AOP 不一样,
		//    感兴趣的读者请参考我写的关于 AspectJ 的另一篇文章 https://www.javadoop.com/post/aspectj
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
		/**
		 * 从下面几行代码我们可以知道,Spring 往往很 "智能" 就是因为它会帮我们默认注册一些有用的 bean,
		 * 我们也可以选择覆盖
		 */

		// Register default environment beans.
		// 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		// 如果没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		// 如果没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

接下来我们开始进入到finishBeanFactoryInitialization这个方法,关于前面的几个方法这边再贴一下

                // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
				// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
				// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
				// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 从方法名就可以知道,典型的模板方法(钩子方法),
				// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
				onRefresh();

				// Check for listener beans and register them.
				// 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,直接过
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有的 singleton beans
				//(lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后,广播事件,ApplicationContext 初始化完成
				finishRefresh();

进入到本次IOC源码的高潮部分了,请大家系好安全带,即将发车…

实例化Bean

进入AbstractApplicationContextfinishBeanFactoryInitialization方法

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 首先,初始化名字为 conversionService 的 Bean。
		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.
		// 这是 AspectJ 相关的内容,放心跳过吧
		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.
		// 到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 看这里  开始初始化
		beanFactory.preInstantiateSingletons();
	}

进入preInstantiateSingletons方法,拿到刚刚beanFactory注册BeanDefinition的名字集合,遍历,可能存在继承关系,如果有则合并,然后判断bean是否是抽象的单例的,懒加载的,满足要求然后再判断该bean是否是个FactoryBean,isFactoryBean方法主要还是通过instanceof来判断的,前面那道面试题我们已经讲了FactoryBean和普通Bean的区别,取得话就在于beanName前面有无"&"

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("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.
		// this.beanDefinitionNames 保存了所有的 beanNames
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
		for (String beanName : beanNames) {
			// 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent,用的不多吧,
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					// 处理 FactoryBean
					// FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号。再调用 getBean,getBean 方法别急
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						// 判断当前 FactoryBean 是否是 SmartFactoryBean 的实现,此处忽略,直接跳过
						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) 这个方法就可以进行初始化了                    
					//看这里!!!!!!!!    
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
		// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,忽略
		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.java
来到了getBean方法

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

doGetBean 注意 有2个getSingleton,3个getObjectForBeanInstance,这块一定要逐个分析一下

	//告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
							  @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//1.转换对应的beanName
		// 获取一个 “正统的” beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),
		// 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的
		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		//2.直接尝试从缓存获取或者 singleton Factories 巾的 Object Factory 获垠
		// 这里说下 args 呗,虽然看上去一点不重要。前面我们一路进来的时候都是 getBean(beanName),
		// 所以 args 传参其实是 null 的,但是如果 args 不为空的时候,那么意味着调用方不是希望获取 Bean,而是创建 Bean
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				} else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//3.如果从缓存中得到了bean的原始状态,则对bean进行实例化
			// 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance,
			// 如果是 FactoryBean 的话,返回它创建的那个实例对象
			// (FactoryBean 知识,读者若不清楚请移步附录)
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			/**
			 * 只有在单例的情况才会尝试解决循环依赖,原型模式情况下,如果存在
			 * A 中有B的属性,那么当依赖注入的时候,就会产生当且还未创建完的时候因为
			 * 对于B 创边再次返回创建A ,造成循环依赖, 也就是下面的情况
			 */
			//4.原型模式的依赖检查
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			//检查一下这个BeanDefinition 在容器中是否存在
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//如果beanDefinitionMap中也就是在所有已经加载的类中不包括beanName则尝试从parentBeanFactory中检测
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				//递归到beanFactory中寻找
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				} else if (args != null) {
					// Delegation to parent with explicit args.
					//委派父级容器根据指定名称和显式的参数查找
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				} else {
					// No args -> delegate to standard getBean method.
					//委派父级容器根据指定名称和类型查找
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			//如果不是仅仅做类型检查则是创建bean,这里要进行记录
			if (!typeCheckOnly) {
				// typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。向容器标记指定的Bean已经被创建
				markBeanAsCreated(beanName);
			}
			/*
			 * 稍稍总结一下:
			 * 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean;
			 * 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。
			 */

			try {
				//将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性
				//主要解决Bean继承时子类合并父类公共属性问题
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 先初始化依赖的所有 Bean,这个很好理解。
				// 注意,这里的依赖指的是 depends-on 中定义的依赖
				String[] dependsOn = mbd.getDependsOn();
				//若存在依赖则需要递归实例化依赖的bean
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//缓存依赖调用,注册一下依赖关系
						registerDependentBean(dep, beanName);
						try {
							//递归调用getBean()方法,先初始化被依赖项
							getBean(dep);
						} catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				// 如果是 singleton scope 的,创建 singleton 的实例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//执行创建 Bean , 详解后面再说
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				} else if (mbd.isPrototype()) {
					//多例模式的创建
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						// 执行创建 Bean
						prototypeInstance = createBean(beanName, mbd, args);
					} finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				} else {
					//如果不是 singleton 和 Prototype 的话,需要委托给相应的实现类来处理
					//指定的scope创建bean
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								// 执行创建 Bean
								return createBean(beanName, mbd, args);
							} finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					} catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
										"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			} catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		// 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			} catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

第一个getSingleton
然后到getSingleton方法,注意allowEarlyReference为true表示Spring默认是支持循环依赖的,这段逻辑到第一个判断就直接返回了,原因在于isSingletonCurrentlyInCreation方法,点进去就是判断这个beanName是否在这个Set中,不满足直接返回了Null

	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}
	//然后到getSingleton方法,注意allowEarlyReference为true表示Spring默认是支持循环依赖的
		@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//	第一次进来this.singletonObjects.get(beanName)返回的肯定是null。然后isSingletonCurrentlyInCreation决定了能否进入二级缓存中获取数据。
			synchronized (this.singletonObjects) {
				//从二级缓存获取
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//调用预先设定的getObject()方法
						singletonObject = singletonFactory.getObject();
						//记录在缓存中,earlySingletonObjects和singletonFactories互斥
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

然后因为sharedInstance为空所以if不满足走else,然后到了这一步,对原型的检查

	//4.原型模式的依赖检查
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			//如何判断的,这里涉及到一个ThreadLocal的概念,目前为空,
				protected boolean isPrototypeCurrentlyInCreation(String beanName) {
		Object curVal = this.prototypesCurrentlyInCreation.get();
		return (curVal != null &&
				(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
	}

然后就是一系列判断,拿到我们前面注册到bean工厂的BeanDefinition对象,也就是这里的RootBeanDefinition,判断他是单例的还是多例的还是其他的,然后走各自对应的处理逻辑,目前我们的beanName为messageService,默认单例,所以我们又到了看第二个getSingleton方法。

对于下面这段代码,有个lambda表达式,也许有的老铁就慌了,莫慌莫慌。调试一下…

				// 如果是 singleton scope 的,创建 singleton 的实例
				if (mbd.isSingleton()) {
				    //看这里
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//执行创建 Bean , 详解后面再说
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				} else if (mbd.isPrototype()) { ...}

断点调试首先进来getSingleton方法,仔细看图类名+$lambda,这是什么鬼????
在这里插入图片描述
然后我们看下ObjectFactory,代码如下:

@FunctionalInterface
public interface ObjectFactory<T> {
	/**
	 * Return an instance (possibly shared or independent)
	 * of the object managed by this factory.
	 * @return the resulting instance
	 * @throws BeansException in case of creation errors
	 */
	 //返回一个由此工厂管理的实例,
	T getObject() throws BeansException;
}

然后这个lambda表达式是在调用getObject()方法的时候触发的,小伙伴们可以自己断点试试,这也算一个亮眼的操作了…继续讲解getSingleton方法

前面我们在if(isSingletonCurrentlyInCreation)有个判断,如果成立则会抛出循环依赖的异常信息,
到这个getSingleton方法里的beforeSingletonCreation方法才是往singletonsCurrentlyInCreation添加当前的beanName。

然后就是调用singletonFactory.getObject();也就是AbstractBeanFactory的getSingleton的lambda这块一定要注意。

到了finally的afterSingletonCreation方法,就把singletonsCurrentlyInCreation的beanName给拿掉
如果lambda执行没问题newSingleton赋值为true,然后执行addSingleton方法。

到这里,单例bean的外部逻辑我们已经锊清楚了。
下面是getSingleton方法和里面几个重要方法的代码。

	//因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
	// Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦
	//下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory.
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//断言beanName肯定不为空
		Assert.notNull(beanName, "Bean name must not be null");
		//同步全局变量,开始创建单例
		synchronized (this.singletonObjects) {
			//查看单例是否已经被加载,凡是加载过的单例,都会存在Map<String, Object> singletonObjects里面
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				//this.singletonsCurrentlyInDestruction是个boolean,记录的是当前这个单例是否正在被销毁,
				//如果是true,代表单例已经执行了自身的destroy销毁方法,或者有异常的时候执行了destroySingleton方法等情况
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
									"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//从一级缓存中取肯定为NULL,这里往singletonsCurrentlyInCreation添加beanName
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				//如果此时suppressedExceptions为空,就new LinkedHashSet<>()来保存接下来可能发生的异常
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//到这里就会调用外面的lambda表达式
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				} catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					//如果没有创建报错
					if (singletonObject == null) {
						throw ex;
					}
				} catch (BeanCreationException ex) {
					//把出现过的异常加进去
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				} finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//后处理,主要是把刚刚在beforeSingletonCreation方法里面加载的bean状态删除
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//把结果存在缓存中,并删除一些中间状态
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

beforeSingletonCreation方法

	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

然后finally的afterSingletonCreation方法

	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

addSingleton方法

	if (newSingleton) {
					//把结果存在缓存中,并删除一些中间状态
		addSingleton(beanName, singletonObject);
	}
创建Bean

也就是执行我们的lambda内容,IOC核心部分要来了

	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		//要注意,在我们的初始化阶段,args 是 null。
		if (logger.isDebugEnabled()) {
			logger.debug("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.
		// 确保 BeanDefinition 中的 Class 被加载
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		// 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />
		// 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的地方看看对这两个标签的解析。
		// 我在附录中也对这两个标签的相关知识点进行了介绍,读者可以移步去看看
		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.
			// 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,
			// 在 《Spring 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.isDebugEnabled()) {
				logger.debug("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);
		}
	}

进入doCreateBean方法,1,2,3为其中的重点

	//标记1,2,3是doCreateBean方法中3个比较重要的点
	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) {
			//  1.说明不是 FactoryBean,这里实例化 Bean,这里非常关键,细节之后再说
			//根据指定Bean使用对应的策略创建Bean实例:如工厂方法,构造函数自动注入,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 这个就是 Bean 里面的 我们定义的类 的实例,很多地方我直接描述成 "bean 实例"
		final Object bean = instanceWrapper.getWrappedInstance();
		// 类型
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				} catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		// 下面这块代码是为了解决循环依赖的问题,以后有时间,我再对循环依赖这个问题进行解析吧
		//是否需要提前曝光,判断条件为:单例&允许循环依赖&是否正在创建过程中
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		//允许提前暴露,添加到三级缓存中
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//添加到三级缓存中
			//对bean再一次依赖引用。主要应用于SmartInstantiationAwareBeanPostProcessor
			//其中我们熟知的AOP的advice就是在这里动态织入到bean中...若没有则直接返回bean
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 2.这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
			populateBean(beanName, mbd, instanceWrapper);
			// 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?
			// 3.这里就是处理 bean 初始化完成后的各种回调
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		} catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			} else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			//如果是A和B存在循环依赖关系,在B的生命周期调用完了后置处理器之后到这,因传入false,导致为空,为什么要传入false,是因为A此时已经完了后置处理器,但A这个Bean
			//其实没有创建完,如果还想生成代理类,是有问题的,这也就是为什么spring二级缓存不用,选择三级缓存的原因
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
										StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
										"] in its raw version as part of a circular reference, but has eventually been " +
										"wrapped. This means that said other beans do not use the final version of the " +
										"bean. This is often the result of over-eager type matching - consider using " +
										"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

推断构造方法

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		// 确保已经加载了此 class
		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());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		//如果工厂方法不为空则使用工厂方法初始化策略,其实也对是对应xml的<bean factory-method>标签
		if (mbd.getFactoryMethodName() != null) {
			// 采用工厂方法实例化,不熟悉这个概念的读者请看附录,注意,不是 FactoryBean
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		// 如果不是第一次创建,比如第二次创建 prototype bean。
		// 这种情况下,我们可以从第一次创建知道,采用无参构造函数,还是构造函数依赖注入 来完成实例化
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				//一个类中可能有多个构造函数,每个构造函数都有不同的参数,所以调用前需要先根据参数锁定构造函数对应的工厂方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				// 构造函数依赖注入
				return autowireConstructor(beanName, mbd, null, null);
			} else {
				// 无参构造函数
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		// 判断是否采用有参构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == 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);
	}

本次我们调用的是无参构造方法,所以进入到instantiateBean,可以看到Spring将实例化的bean封装成了一个BeanWrapper的包装类

	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		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);
		}
	}

进入到Bean初始化策略的instantiate方法,大体逻辑我们分析一下
1.判断bd存不存在方法覆写,默认没有,所以进if,他先回去尝试一下能不能拿到我们要用的构造,也就是定义的constructorToUse,正常情况下没配置都是拿不到,所以为NULL,再进去,通过bd拿到我们的Class,看到这里,是不是就是我们java的反射知识了,继续看,他会判断这个class是不是一个接口,如果是就是抛出RuntimeException类型异常。顺便再提一点,我们工作中,关于service层,注意是service层的接口哈,为什么接口不用加注解,而在结尾为Impl的实现类加了注解@Service的原因,所以看源码对平常工作还是有一定帮助的。

	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		// 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB,这里就是判断采用什么初始化bean的策略
		// 方法覆写 eg: lookup-method 和 replaced-method 
		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);
					}
				}
			}
			// 利用构造方法进行实例化
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			// 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类
			//  因为如果不使用 CGLIB 的话,存在 override 的情况 JDK 并没有提供相应的实例化支持
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

上面通过反射拿到我们的构造,接下来传入到一个BeanUtils的工具类进行实例化

	public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
		//主要判断构造的修饰符,是不是能访问,如果是私有的,或者不能访问,那么我们就需要进行暴力访问
		//也就是加上这行代码  ctor.setAccessible(true);
			ReflectionUtils.makeAccessible(ctor);
			//调用初始化策略,目前默认是newInstance来实例化的
			return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
		}
		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());
		}
	}

这个时候我们控制台打印了一句话,通过这个打印我们能清楚的知道这个通过构造进行实例化的
在这里插入图片描述

提前暴露工厂

实例化Bean讲完了,下面这段代码很重要,设及到Spring比较难的知识点:循环依赖

下面这块代码是为了解决循环依赖的问题,earlySingletonExposure正常情况下都是true的,isSingletonCurrentlyInCreation(beanName),还记得前面一个方法叫beforeSingletonCreation这个么,我们这里还没有到afterSingletonCreation方法呢,还在lambda表达式里的getObject()方法实例化Bean呢,小伙伴们可千万别懵了。
然后到addSingletonFactory方法,这里又传了一个lambda,道理跟咋们前面讲的一样,

      
		//是否需要提前曝光,判断条件为:单例&允许循环依赖&是否正在创建过程中
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		//允许提前暴露,添加到三级缓存中
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//添加到三级缓存中
			//对bean再一次依赖引用。主要应用于SmartInstantiationAwareBeanPostProcessor
			//其中我们熟知的AOP的advice就是在这里动态织入到bean中...若没有则直接返回bean
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

addSingletonFactory方法

	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			//一级缓存不存在
			if (!this.singletonObjects.containsKey(beanName)) {
				//放入三级缓存中
				this.singletonFactories.put(beanName, singletonFactory);
				//移除二技缓存
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

Q:这里设及到Spring三级缓存方面的问题,由于本篇文章篇幅确实过长了,所以后期考虑开一篇文章来重点讲讲循环依赖,以及Spring为什么要使用三级缓存来解决该问题的?

继续第二步,DI部分

依赖注入(DI)
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			} else {
				// Skip property population phase for null instance.
				//没有需要填充的属性
				return;
			}
		}
		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		// 1.InstantiationAwareBeanPostProcessor 处理器的postProcessAfterInstantiation函数的应用,此函数可以控制程序是否继续进行属性填充
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
		// bean 实例的所有属性都在这里了
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		// 2. 根据注入类型,提取依赖的bean,并统一存入PropertyValues中
		//没配置的话默认为0 关于名字,类型,构造分别对应1,2,3
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				// 通过类型装配。复杂一些
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		//后处理器已经初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//需要依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			// 3. 应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性再次处理
			//典型应用是RequiredAnnotationBeanPostProcessor类中对属性的验证
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						// 这里有个非常有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor
						// 对采用 @Autowired、@Value 注解的依赖进行设值,这里的内容也是非常丰富的,不过本文不会展开说了,感兴趣的读者请自行研究
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		// 4. 将PropertyValues属性填充到BeanWrapper中
		if (pvs != null) {
			// 设置 bean 实例的属性值   看这里
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

进入到第四步,前面主要是一些条件判断,然后拿到属性名字,原始值,这个原始值可能还不是我们要使用的,需要再处理一下,于是,下一步…

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			//如果mpvs中的值已经被转换为对应的类型那么可以直接设值到bw中
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				} catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			//如果 pvs 并不是使用 MutablePropertyValues 封装的类型,那么直接使用原始的属性获取方法
			original = mpvs.getPropertyValueList();
		} else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//获取对应·的解析器
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		//遍历属性,将属性转换为对应类的对应属性的类型
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			} else {
				String propertyName = pv.getName();
				//原始的属性值,即转换之前的属性值
				Object originalValue = pv.getValue();
				//做一些类型的强制转换
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				//转换之后的属性值
				Object convertedValue = resolvedValue;
				//属性值是否可以转换
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				} else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				} else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			// AbstractPropertyAccessor
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		} catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

进入BeanDefinitionValueResolverresolveValueIfNecessary方法
判断value是不是运行时Bean的引用,显然这里是,进入第一个return方法

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);
		}
		else if (value instanceof RuntimeBeanNameReference) {
			String refName = ((RuntimeBeanNameReference) value).getBeanName();
			refName = String.valueOf(doEvaluate(refName));
			if (!this.beanFactory.containsBean(refName)) {
				throw new BeanDefinitionStoreException(
						"Invalid bean name '" + refName + "' in bean reference for " + argName);
			}
			return refName;
		}
		else if (value instanceof BeanDefinitionHolder) {
			// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
			BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
			return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
		}
		else if (value instanceof BeanDefinition) {
			// Resolve plain BeanDefinition, without contained name: use dummy name.
			BeanDefinition bd = (BeanDefinition) value;
			String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
					ObjectUtils.getIdentityHexString(bd);
			return resolveInnerBean(argName, innerBeanName, bd);
		}
		else if (value instanceof ManagedArray) {
			// May need to resolve contained runtime references.
			ManagedArray array = (ManagedArray) value;
			Class<?> elementType = array.resolvedElementType;
			if (elementType == null) {
				String elementTypeName = array.getElementTypeName();
				if (StringUtils.hasText(elementTypeName)) {
					try {
						elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
						array.resolvedElementType = elementType;
					}
					catch (Throwable ex) {
						// Improve the message by showing the context.
						throw new BeanCreationException(
								this.beanDefinition.getResourceDescription(), this.beanName,
								"Error resolving array type for " + argName, ex);
					}
				}
				else {
					elementType = Object.class;
				}
			}
			return resolveManagedArray(argName, (List<?>) value, elementType);
		}
		else if (value instanceof ManagedList) {
			// May need to resolve contained runtime references.
			return resolveManagedList(argName, (List<?>) value);
		}
		else if (value instanceof ManagedSet) {
			// May need to resolve contained runtime references.
			return resolveManagedSet(argName, (Set<?>) value);
		}
		else if (value instanceof ManagedMap) {
			// May need to resolve contained runtime references.
			return resolveManagedMap(argName, (Map<?, ?>) value);
		}
		else if (value instanceof ManagedProperties) {
			Properties original = (Properties) value;
			Properties copy = new Properties();
			original.forEach((propKey, propValue) -> {
				if (propKey instanceof TypedStringValue) {
					propKey = evaluate((TypedStringValue) propKey);
				}
				if (propValue instanceof TypedStringValue) {
					propValue = evaluate((TypedStringValue) propValue);
				}
				if (propKey == null || propValue == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Error converting Properties key/value pair for " + argName + ": resolved to null");
				}
				copy.put(propKey, propValue);
			});
			return copy;
		}
		else if (value instanceof TypedStringValue) {
			// Convert value to target type here.
			TypedStringValue typedStringValue = (TypedStringValue) value;
			Object valueObject = evaluate(typedStringValue);
			try {
				Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
				if (resolvedTargetType != null) {
					return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
				}
				else {
					return valueObject;
				}
			}
			catch (Throwable ex) {
				// Improve the message by showing the context.
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Error converting typed String value for " + argName, ex);
			}
		}
		else if (value instanceof NullBean) {
			return null;
		}
		else {
			return evaluate(value);
		}
	}

看到这里,不知道小伙伴是明白了还是懵了,哈哈,我们说说这断代码:拿到beanName,然后判断,又是一个beanFactory,没错,这就是我们前面得到的DefaultListableBeanFactory,IOC的始祖

	@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		try {
			Object bean;
			String refName = ref.getBeanName();
			refName = String.valueOf(doEvaluate(refName));
			if (ref.isToParent()) {
				if (this.beanFactory.getParentBeanFactory() == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Can't resolve reference to bean '" + refName +
									"' in parent factory: no parent factory available");
				}
				bean = this.beanFactory.getParentBeanFactory().getBean(refName);
			}
			else {
				//-----------------------------看这里------------------------------------------
				bean = this.beanFactory.getBean(refName);
				this.beanFactory.registerDependentBean(refName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					this.beanDefinition.getResourceDescription(), this.beanName,
					"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
		}
	}

进入getBean方法
又到了我们最初的messageService的起点了,不过这次是beanName为message的bean

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

这是我们开始的xml配置

	<bean id="messageService" name="m1,m2,m3" scope="singleton" class="com.whp.service.impl.MessageServiceImpl">
		<!--引入下面id为message的bean-->
		<property name="message" ref="message"/>
	</bean>
	<bean id="message" class="com.whp.bean.Message"/>

然后重复messageService之后,我们拿到了beanName为message的bean,这时候需要给MessageServiceImpl这个类的属性message赋值了,还是我们前面的DI的过程,然后接下来就是赋值了。

Bean实例化完成函数回调

前面2步我们已经把Bean实例化以及DI完成了,最后就是回调以及通知了,工作亦是如此…

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		//JDK的安全机制验证权限
		if (System.getSecurityManager() != null) {
			//实现PrivilegedAction接口的匿名内部类
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		} else {
			// 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// BeanPostProcessor 的 postProcessBeforeInitialization 回调
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 处理 bean 中定义的 init-method,
			// 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法
			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()) {
			// BeanPostProcessor 的 postProcessAfterInitialization 回调
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

部分Aware回调
进入invokeAwareMethods方法,这部分我们叫做部分Aware回调,这里就三个,对于Aware接口的实现肯定有多个,所以这里我们叫部分Aware接口回调

	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

还记得嘛,我开始在MessageServiceImpl实现了BeanNameAware,然后setBeanName方法,就是为了这一步
在这里插入图片描述
然后到了BeanPostProcessor的前后通知
applyBeanPostProcessorsBeforeInitialization方法

	@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

applyBeanPostProcessorsAfterInitialization方法

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

对于BeanPostProcessor,是Spring提供给我们开发者的一个非常重要的拓展点,还有FactoryBean
InitializingBean我们也可以利用它来初始化我们自定义的一些Bean,Aware接口我们也可以利用起来
第3步完成过后有个if (earlySingletonExposure) {…}这块属于循坏依赖东西,后期有时间会开篇文章重点讲讲。
这个时候我们的beanName为messageService的Bean实例化完成了,最后需要把它放入到Spring的一级缓存中,供开发者使用。
在这里插入图片描述
afterSingletonCreation(beanName)将singletonsCurrentlyInCreation的beanName移除

	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

addSingleton方法

	//一句话,Bean添加到一级缓存,移除二三级缓存。
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			//一级缓存添加
			this.singletonObjects.put(beanName, singletonObject);
			//移除三级,二级缓存
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			//	registeredSingletons这个Set是记录已经创建好的bean
			this.registeredSingletons.add(beanName);
		}
	}

最后一个就是getObjectForBeanInstance方法了

				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//执行创建 Bean , 详解后面再说
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				} else if (mbd.isPrototype()) {

* 这个方法就三个判断:
* 1、如果不是factoryBean 但是name开头为&,那么报错
* 2、如果是FactoryBean,并且name开头不为&,就取FactoryBean的getObject方法
* 3、如果是FactoryBean,并且name开头为&,那么返回FactoryBean本身。

	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			//
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				//如果name开头&,但又不是factoryBean就报错
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		//如果不是FactoryBean,那么就属于正常的bean实例了,直接返回
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
		//加载FactoryBean
		Object object = null;
		if (mbd == null) {
			//尝试从缓存中获取bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			//强转为beanFactory。此时的beanInstance一定是FactoryBean类型的,因为如果不是,就会在上面的if中直接返回了
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			//检测这个bean是否已经被加载过
			//containsBeanDefinition中会返回beanDefinitionMap.containsKey(beanName)的值
			if (mbd == null && containsBeanDefinition(beanName)) {
				//进行父类和子类的合并,把存储xml配置的GernericBeanDefinition转换为RootBeanDefinition
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//我的bean是FactoryBean,那么就会通过FactoryBean的getObject方法
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

到这里,可以说是Spring初始化完成了,我们可以通过一下进行调用使用了

MessageService messageService = (MessageService) applicationContext.getBean("messageService");

本次的Spring IOC源码解析已接近了尾声,不知道有多少小伙伴坚持看完了,看完的可以在下方回复Spring IOC,也表示对博主写了这么久的认可哈哈,确实有点辛苦,如果本篇文章有缺点,欢迎指教,需要源码项目的也可以找我要,省的大家去下载了,本次Spring IOC源码解析到此结束。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇见更优秀的自己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值