Spring源码学习(二)

导读:本篇文章讲解 Spring源码学习(二),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

第二章:Spring牛逼的后置处理器



一、温故而知新 spring总流程

在这里插入图片描述

通过跟踪源码,去理解每一个步骤

  • 1.1 spring要干活必须先要有一个工厂(先造一个毛胚房【创建bean工厂】=》然后装修一下【初始化bean工厂】)
    AbstractApplicationContext中Refresh()方法大概12大步骤,从造毛胚房到装修
在这里插入代码片@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 我的==》工厂创建:beanFactory第一次开始创建的时候
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

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

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				// spring容器启动:一工厂创建好后就进行增强,在这个方法中执行bean工厂的后置增强功能
				// 工厂增强:执行所有的BeanFactory后置增强器,利用beanFactory后置增强器对工厂进行修改或者增强
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册bean的后置处理器 Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

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

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

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

				// 注册监听器,spring的监听在这里被注册 跟进查看 Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// bean创建:完成beanFactory的初始化(工厂中所有的组件都好了)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			} catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			} finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
  • 1.2 加载非懒加载实例(厂也装修完了,总要几个不懒的工人先上岗吧)
// 初始化所有的非懒加载的单实例bean
beanFactory.preInstantiateSingletons();

因为一开始就有人来应聘了(bean定义信息已经注册进来),那么就要一个一个看简历(底层在DefaultListableBeanFactory使用for循环拿出所有的bean信息)。

=》这里从getBean=》doGetBean【这里用了模板方法模式】

  • 1.3 简历拿到了,就要面试招工(创建一个bean实例)
// 创建bean实例 Create bean instance.
				if (mbd.isSingleton()) {
					// lambda表达式这个方法体主要就是为了生成一个实体
					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;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

这里从createBean=》doGreateBean;

默认使用无参构造器去完成bean的创建

if (instanceWrapper == null) {
			// 创建bean实例,默认使用无参构造器,==》所有都是默认空值,组件的原始对象创建
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

1.4 人招到了,录一下工牌里的信息。【就是populateBean属性赋值】
前面的代码有装饰器模式。

// 自动装配,给创建好的对象每个属性进行赋值,跟进方法也会有自动装配的过程
populateBean(beanName, mbd, instanceWrapper);

二、Bean生命周期的完整流程

总览:创建工厂=》制造bean(中间的后置处理器干预)
图片来自雷老师

主要得学习思路就是:容器得几个阶段=》后置处理器什么时候来=》来干嘛
在这里插入图片描述

refresh()重要方法一:invokeBeanFactoryPostProcessors方法

BeanDefinitionRegistryPostProcess后置处理器

主要是bean定义注册中心的增强

  • 1、最先执行的是bean定义信息的注册中心后置处理器
    源码AbstractApplicationContext中的refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory);
    这都是再beanfactory获取完成之后才调用beanfactory的后置处理器
    -2、
    PostProcessorRegistrationDelegate代理类会for循环出所有的bean工厂的增强
for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}

refresh()重要方法一:invokeBeanFactoryPostProcessors方法

BeanFactoryPostProcess后置处理器

bean工厂后置处理
====》以上说明最先注册的是工厂和bean定义注册中心增强最先执行。这两个基础的东西弄完,那么就要弄一下其他的基建设施,供后面使用

refresh()重要方法二:registerBeanPostProcessors();方法

去创建所有的bean后置处理器,让后面在创建bean的时候直接在容器中获取
在这里插入图片描述
统一调用postProcessBeforeInstantiation这个方法去实例化

refresh()重要方法三:registerListeners();方法

注册监听器

SmartInstantiationAwareBeanPostProcessor去预测bean的类型

predictBeanType

refresh()重要方法四:finishBeanFactoryInitialization();方法完成bean工厂的初始化

InstantiationAwareBeanPostProcessor后置处理器

先getBean判断容器中是否已经有值

refresh()重要方法四:finishBeanFactoryInitialization();方法完成bean工厂的初始化

SmartInstantiationAwareBeanPostProcessor后置处理器

返回构造器(默认返回无参构造器)

bean的生命周期开始

1、创建一个bean的实例,使用BeanWrapper

2、属性赋值 populateBean

  • 2.1、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),申请一个后置处理器,去合并bean的定义信息
  • 2.2、 InstantiationAwareBeanPostProcessor=》postProcessAfterInstantiation//返回false则bean的赋值全部结束
  • 2.3、 InstantiationAwareBeanPostProcessor=》postProcessProperties,
    处理属性值

3、初始化InitializeBean

  • 3.1、调用bean的后置处理器

4、完成

5、销毁

getBean流程

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96189.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!