Spring启动过程——源码分析

前言

Spring是什么?
Spring发展至今,已经不是简单的Spring Framework,它包括Spring Data、Spring Boot、Spring Cloud等等组成
不过这里我们仅讨论Spring Framework,重点讨论Spring的启动过程及拓展应用

Spring启动

监听器启动

web.xml配置

Spring通过监听器启动是最常见的方式(后续文章会补上其它启动方式,如用SpringBoot启动等)
ContextLoaderListener实现了ServletContextListener,会在web容器启动的时候调用

进入initWebApplicationContext()
这里只挑重点方法讲 this.context = createWebApplicationContext(servletContext);默认会创建一个XmlWebApplicationContext
而后进入configureAndRefreshWebApplicationContext(cwac, servletContext)

获取所有需要初始化的配置文件sc.getInitParameter(CONFIG_LOCATION_PARAM) 也就是上面一开始配置的context-param标签 最后执行refresh

Spring容器创建过程

refresh()
删减了一些无关紧要的代码

        @Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();
			// Tell the subclass to refresh the internal bean factory.
			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);
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory)
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				// Initialize message source for this context.
				initMessageSource();
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
				// Initialize other special beans in specific context subclasses.
				onRefresh();
				// Check for listener beans and register them.
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
				// Last step: publish corresponding event.
				finishRefresh();
			}
		}
	}
复制代码

prepareRefresh()

容器refresh预准备工作 AbstractApplicationContext

  • initPropertySources() AbstractApplicationContext子类自定义属性设置的方法

  • getEnvironment().validateRequiredProperties() 校验设置属性

  • this.earlyApplicationEvents = new LinkedHashSet<>() 保存容器早期的事件

obtainFreshBeanFactory()

获取工厂

  • refreshBeanFactory()

重点讲下 loadBeanDefinitions(beanFactory);
BeanDefinition是工厂中非常重要的属性,它将所有需要spring管理的bean信息都存储起来,会在后边一个一个去实例化
最终进入

reader.loadBeanDefinitions(configLocation)方法很深,我看了下,代码很深,大致的内容:
根据件用xmlReader去读取一个个配置文件 最终调用
this.beanDefinitionMap.put(beanName, beanDefinition)

refreshBeanFactory执行完进入getBeanFactory()
直接返回改beanFactory 方法结束

prepareBeanFactory(beanFactory)

从上往下四个框框作用分别是

  • 在工厂设置类加载器、表达式解析器

  • 给工厂添加ApplicationContextAwareProcessor(processor先不解释有什么意思 后续会说明)

  • 设置需要忽略的自动装配的接口(EnvironmentAware、ApplicationContextAware等Aware)

  • 给工厂添加 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this))

接着上面方法

最终调用

给容器注册一些组件

  • environment(ConfigurableEnvironment)
  • systemProperties(Map<String, Object>)
  • systemEnvironment(Map<String, Object>)

postProcessBeanFactory(beanFactory)

BeanFactory准备工作完成后 后置处理
空方法 子类自定义属性设置的方法 这里web环境 用的工厂是AbstractRefreshableWebApplicationContext
记住这里只是web端拓展才有的实现

这里先添加了一个ServletContextAwareProcessor和设置需要忽略的自动装配的接口
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext)
添加了几个scope

spring本身只有singleton和prototype两个,web环境加上了request、session、globalSession

invokeBeanFactoryPostProcessors(beanFactory)

这里没仔细看

执行BeanFactory后置处理器 执行这两种处理器
BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
他们的关系:BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor

总的来说

  1. 先获取所有的BeanDefinitionRegistryPostProcessor

  2. 依次执行实现了PriorityOrdered、Ordered接口和没有实现它们的 processor postProcessor.postProcessBeanDefinitionRegistry(registry)
    在这里我debug发现 spring内部有一个ConfigurationClassPostProcessor
    它的作用是负责解析处理所有@Configuration标签类,并将Bean定义(包括其它processor)注册到BeanFactory中
    这里注册完之后 再次获取所有BeanDefinitionRegistryPostProcessor,按顺序执行 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
    重点:其它的BeanDefinitionRegistryPostProcessor就是Spring提供给我们注册bean的通道

  3. 再执行postProcessor.postProcessBeanFactory(beanFactory)

  4. 获取所有的BeanFactoryPostProcessor

  5. 分类执行 执行过的不再执行

6. 依次执行实现了PriorityOrdered、Ordered接口和没有实现它们的 processor postProcessor.postProcessBeanFactory(beanFactory)

实践出真知 这里是用SpringBoot简单搭起的一个demo,跟上面不一样,不过不影响测试结果

执行结果:

结果在意料之中 也就是说

  • 先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry
  • 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory
  • 最后执行BeanFactoryPostProcessor的postProcessBeanFactory

registerBeanPostProcessors(beanFactory)

注册Bean的后置处理器(跟上面的FactoryPostProcessor不一样)

Bean的生命周期: Bean创建--初始化--销毁

不同BeanPostProcessor功能都不一样
BeanPostProcessor的实现子接口:
DestructionAwareBeanPostProcessor InstantiationAwareBeanPostProcessor MergedBeanDefinitionPostProcessor SmartInstantiationAwareBeanPostProcessor
BeanPostProcessor

红色部分:
获取所有BeanPostProcessor 依次注册了PriorityOrdered、Ordered接口、没有实现它们的、MergedBeanDefinitionPostProcessor
注册调用的是
黄色部分:
注册ApplicationListenerDetector :在bean初始化后 检查如果是listener的话 执行applicationContext.addApplicationListener

initMessageSource()

初始化MessageSource组件(做国际化、消息绑定、消息解析)

  1. 获取BeanFactory
  2. 查看容器是否有messageSource的组件
  • 有->this.applicationEventMulticaster beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class)

  • 没有->new DelegatingMessageSource() 注册一个MessageSource组件
    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)

initApplicationEventMulticaster()

初始化事件派发器

和上面实现差不多

  1. 获取BeanFactory
  2. 查看容器是否有applicationEventMulticaster的组件
  • 有->this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class)

  • 没有->new SimpleApplicationEventMulticaster() beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster)

这个派发器在后续很有用

onRefresh()

子类自定义的方法 web环境下直接进入一个空方法
还不确定什么环境下会有执行 欢迎联系交流~

registerListeners()

  1. 获取所有ApplicationListener
  2. getApplicationEventMulticaster().addApplicationListenerBean
    这里拿到的派发器就是刚才注册的

finishBeanFactoryInitialization(beanFactory)

较为复杂,单独作为一篇

finishRefresh()

  1. 初始化和生命周期有关的后置处理器 initLifecycleProcessor()
  • LifecycleProcessor:
  • void onRefresh();
    调用生命周期处理器的onRefresh方法,这个方法会找出Spring容器中实现了SmartLifecycle接口的类并进行start方法的调用
  1. 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
    publishEvent(new ContextRefreshedEvent(this))
  2. 调用LiveBeansView的registerApplicationContext方法:如果设置了JMX相关的属性,则就调用该方法 LiveBeansView.registerApplicationContext(this)

转载于:https://juejin.im/post/5caef238e51d456e27504b83

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值