Spring | Spring源码解析之Bean实例化流程

一、寻找Spring 入口 ApplicationContext.refresh()

1. SpringBoot 入口

我是通过SpringBoot 项目进入查看的,现在基本都是SpringBoot 项目了 大家依照这个查看的话也会方便点;


SpringApplication.run -> run(String… args) -> this.refreshContext(context) -> this.refresh(context) -> applicationContext.refresh()


在这里插入图片描述

2. SpringApplication run(String… args) 代码注释

这里需要了解一下 SpringApplication 中的 run(String… args) 方法 看注释;

public ConfigurableApplicationContext run(String... args) {
		//创建时间记录类
		StopWatch stopWatch = new StopWatch();
		//启动时间记录
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		//设置系统属性
		configureHeadlessProperty();
		//创建所有 Spring 运行监听器并发布应用启动事件
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			//加载服务&系统资源
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			//打印SpringBoot 启动日志   就那个图形化日志
			//Banner的日志
			Banner printedBanner = printBanner(environment);

			//创建ConfigurableApplicationContext
			context = createApplicationContext();

			// springboot 自动装配 方法 获取  META-INF/spring.factories 文件下的所有
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);//获取 context 封装

			//spring ioc 核心方法 内部调用 ((AbstractApplicationContext) applicationContext).refresh()
			refreshContext(context);//

			afterRefresh(context, applicationArguments);
			//停止时间记录
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

二、核心 AbstractApplicationContext.refresh()

1. AbstractApplicationContext.refresh() 代码与注释

源码截图
在这里插入图片描述
代码注释

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 准备资源 context上下文
			prepareRefresh();

			// 创建容器 工厂  这里进行XML/注解 解析获取到BeanDefination
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// BeanFactory 的准备工作 BeanFactory的属性赋值工作
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//允许在context子类中对bean工厂进行扩展实现。 空方法  模板方法 忽略
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//调用在上下文中的BeanFactoryPostProcess  工厂处理器。 如PlaceholderConfigurerSupport 处理占位符
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册BeanFactoryPostProcess 准备好
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//  忽略 国际化配置
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化事件监听多路广播器。  观察者模式
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//留给子类扩展使用  模板方法 空方法  springboot 中tomcat 实在这里注入的
				onRefresh();

				// Check for listener beans and register them.
				//检查Listener bean并注册它们。 观察者模式
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//实例化所有剩余的(非lazy-init)单例 从这里开始Bean创建的工作。Bean的生命周期在这里进行
				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();
			}
		}
	}

2. Bean实例化流程 面试常面内容

  1. prepareRefresh();// 准备资源 context上下文。
  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 创建容器工厂,这里进行XML/注解 解析获取到BeanDefination。
  3. prepareBeanFactory(beanFactory); // BeanFactory 的准备工作 BeanFactory的属性赋值工作。
  4. postProcessBeanFactory(beanFactory); //允许在context子类中对bean工厂进行扩展实现。 空方法 模板方法 忽略。
  5. invokeBeanFactoryPostProcessors(beanFactory); //调用在上下文中的BeanFactoryPostProcess 工厂处理器。 如PlaceholderConfigurerSupport 处理占位符。
  6. registerBeanPostProcessors(beanFactory); //注册BeanFactoryPostProcess 准备好。
  7. initMessageSource(); //国际化配置(忽略)。
  8. initApplicationEventMulticaster(); //初始化事件监听多路广播器(观察者模式)。
  9. onRefresh(); //留给子类扩展使用,模板方法空方法,springboot 中tomcat 实在这里注入的。
  10. registerListeners(); //检查Listener bean并注册它们( 观察者模式)。
  11. finishBeanFactoryInitialization(beanFactory);//实例化所有剩余的(非lazy-init)单例 从这里开始Bean创建的工作。Bean的生命周期在这里进行

从这里开始对象实例化流程开始了

finishBeanFactoryInitialization() -> beanFactory.preInstantiateSingletons() -> getBean(beanName) -> createBean(beanName, mbd, args) -> doCreateBean() 重点


doCreateBean() 方法创建Bean的方法流程如下:

  1. createBeanInstance();// 反射实例化 然后调用

  2. addSingletonFactory();// 将对象放到 singletonFactories (三级缓存中)

  3. populateBean(); //自定义属性赋值 DI 注入

  4. initializeBean();//执行BeanFactoryAware -> BeanPostProcessor 前置处理 -> 初始化方法 -> BeanPostProcessor 后置方法

    1. invokeAwareMethods();// 实现BeanFactoryAware 接口的对象会在invokeAwareMethods中 进行BeanFactory的赋值。代码中: 	((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                  
    2.  applyBeanPostProcessorsBeforeInitialization();//执行前处理方法  实现BeanPostProcessor 的Bean 执行前置处理方法
                  
    3. invokeInitMethods();//执行初始化方法 实现接口 InitlizingBean  调用 afterPropertiesSet()
                  
    4.  applyBeanPostProcessorsAfterInitialization();//后置处理方法    完成Bean的扩展工作 AOP操作在这。AbstractAutoProxyCreator 后置方法 完成代理类的创建  前置实现方法 跟 后置实现 不在一个类中 可以自主选择
    
  5. getSingleton();//对象创建完成之后 调用 getSingleton()-> addSingleton 加入一级缓存 删除 二级 三级缓存


3.总结 (面试阐述)

Spring Bean的实例化流程

        我们现在基本都使用 SpringBoot 快速开发 ,在SpringBoot 项目启动过程成执行 run()方法, run方法中会进行一些SpringBoot 的资源等创建ApplicationContext 工厂等。其中核心的是通过方法调用 AbstractApplicationContext.refresh() 方法 这里是Spring的执行入口,

        当AbstractApplicationContext refresh() 方法执行 会进行准备资源、创建BeanFactory工厂 等操作, 然后执行finishBeanFactoryInitialization(beanFactory) 方法 来进行 Bean的实例化。

        finishBeanFactoryInitialization 内部调用 beanFactory 的 preInstantiateSingletons() 然后这个方法中 通过getBean()方法 中的 createBean() 方法进行创建对象。
        其中 createBean() 方法 内部调用了 doCreateBean()方法,doCreateBean() 中会通过 createBeanInstance()方法使用反射初始化对象,然后调用 addSingletonFactory加入三级缓存中,之后会调用populateBean() 进行DI属性注入,再然后调用 initializeBean() 方法执行 BeanFactoryAware 进行Spring内部对象的赋值注入,之后调用 BeanPostProcessors 前置处理方法 在之后 执行 invokeInitMethods() 初始化方法 最后执行 BeanPostProcessors 后置处理方法(这里是进行AOP增强的)在都执行完成以后 这个对象算是实例化完成了,之后会调用getSingleton()方法 中 addSingleton 将实例化好的Bean从其他缓存中删除加入一级缓存。

三、Spring 三级缓存的作用

  • 三级缓存 singletonFactories HashMap. 创建中的对象半成品对象
  • 二级缓存earlySingletonObjects HashMap AOP 对象 主要解决 AOP 产生的代理对象
  • 一级缓存 singletonObjects CurrentHashMap 创建完成的对象 与 AOP代理对象

阐述

个人总结 有疑问或者 有错误的地方请评论 指出 共同进步谢谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一介草民丶

谢谢老板的一分钱

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

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

打赏作者

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

抵扣说明:

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

余额充值