Spring启动流程

Spring启动流程

启动容器的第一步 执行构造方法GenericApplicationContext

会初始化一个 beanFactory 是 DefaultListableBeanFactory

在DefaultListableBeanFactory的构造方法中

会往 ignoredDependencyInterfaces 中 加入回调类 BeanNameAware BeanFactoryAware BeanClassLoaderAware

第二部 会往application中加入两个东西

AnnotatedBeanDefinitionReader

在这个类的构造方法中会有一些,非常重要的东西

这些都是 设置到 了 beanFactory

直接new出来 并设置到属性中

AnnotationAwareOrderComparator(比较器)

ContextAnnotationAutowireCandidateResolver(依赖注入的 条件类 )–责任链

向BDMap中添加一些东西

ConfigurationClassPostProcessor(配置类的) – internalConfigurationAnnotationProcessor

AutowiredAnnotationBeanPostProcessor(@Autowired)-- internalAutowiredAnnotationProcessor

CommonAnnotationBeanPostProcessor(@Resource) – internalCommonAnnotationProcessor

EventListenerMethodProcessor(事件监听)-- internalEventListenerProcessor

功能 解析 EventListener  注解的
(这是一个BeanFactoryProcess 	和 *SmartInitializingSingleton*)

SmartInitializingSingleton提供的一个方法 afterSingletonsInstantiated(所有单例bean都创建后才会执行	的一个方法 , 这里大概就会 所有单例bean都创建后,会遍历 , 看看哪些bean实现	SmartInitializingSingleton,就会调用afterSingletonsInstantiated)
 
 
EventListenerMethodProcessor的 afterSingletonsInstantiated方法中 会获得所有BD定义的对象

然后会遍历这些 对象 中的方法 看看有没有哪个方法上面加了 @EventListener 然后将这些方法放到一个
annotatedMethods中
然后对这个 集合 中的每一个方法 都会 封装成一个监听器 然后放到事件发布器中


DefaultEventListenerFactory(事件监听) – internalEventListenerFactory

ClassPathBeanDefinitionScanner

这个类的构造方法

主要就是向 includeFilters 中 添加一个 Component注解

执行register方法

会将我们传的类 KangConfiger的类 进行注册

用这个AnnotatedBeanDefinitionReader 将这个类 转为 BD

生成默认的beanName

并 解析 @Scope @Lazy @Primary @DependsOn @Role @Description

将这个 类 放到 BDMap中

refresh(最复杂的方法)

这个方法 用到了 模板的设计模式

这个方法是 AbstractApplicationContext 中定义了一个模板

这个模板

prepareRefresh(); 为刷新做准备

initPropertySources();

这个方法 AbstractApplicationContext 没有没有实现 ,

但 如果子类 调用了 refresh方法,如果实现了这个方法就会去调用这个方法

这就是模板设计的精髓

举一个 实际的例子

AnnotationConfigWebApplicationContext的父类

AbstractRefreshableWebApplicationContext的这个initPropertySources方法会将web.xml的文档转换为key-value的格式,并设置到环境变量中

getEnvironment().validateRequiredProperties();

进行环境变量的校验

我们可以再 刷新前 指定一个环境变量的key的

annotationConfigApplicationContext.getEnvironment().setRequiredProperties(“132”);

会将这个 “123” 转换为一个 requiredProperties 的集合

如果再这一步,去遍历requiredProperties 集合,然后去环境变量里找,如果有一个没有找到,就会抛异常

一个小机制

obtainFreshBeanFactory 也是一个模板方法

这个重复刷新有关系

还有一个就是 获得beanFactory

如果不是web容器 AnnotationConfigApplicationContext 就会 禁止重复刷新,如果重复就会报错

是web容器 , 就允许重复刷新

重复刷新 : 会销毁所有的bean ,在这之前会执行bean的销毁方法(有就执行),然会清空beanFactory

​ 相当于重启了

prepareBeanFactory(beanFactory)

对beanFactory 再次进行加工

给 beanFactory 添加一个 类加载器

开启beanFactorySpel**功能

添加一些 类型 转化器(String 转化 为 spring默认支持的类型)

向beanFactory中的beanPostProcessList中添加一个 ApplicationContextAwareProcessor 对象

处理一些 aware的回调

注册一些接口

		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.ignoreDependencyInterface(ApplicationStartupAware.class);

ignoreDependencyInterface这个集合到底有什么用(不是很重要)

和依赖注入有关系

当我们通过xml注入bean的时候,如果设置是根据类型/名字注入,就会遍历所有set方法,但是真正被作为pvs的前提是,就是这个bean实现的接口不在这个ignoreDependencyInterface集合中,因为这个集合中放的都是一些回调函数,会在初始化前调用这个方法,就是解决了,回调函数和依赖注入(不要重复调用这个set方法)

但是@Autowired并没有这个前提判断,如果将@Autowired加到回调方法上,就会调用两次这个方法

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

这段代码 会往 resolvableDependencies 这个map《class,object》中添加

resolvableDependencies 这个是在 依赖注入 的findAutowireCandidates中

会根据类型 找到这个集合中的对象 并根据一些spring特殊规则(不是正常规则)生成一个beanname

然后放到 result 中

这也是为啥 我们可以通过这种方式 获得 applicationContext

	@Autowired
	ApplicationContext applicationContext;
		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// ApplicationListenerDetector负责把ApplicantsListener类型的Bean注册到ApplicationContext中
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

向beanPostProcessList中添加一个ApplicationListenerDetector对象(事件监听)

		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}

向单例池里面添加一些 有关 environment 的单例bean

postProcessBeanFactory(和web有关)

invokeBeanFactoryPostProcessors(很重要)

功能如其名 执行 beanFactoryPostProcess (操作BD 但是不能增加BD)和 它的子类 BeanDefinitionRegistryPostProcessor 可以增加BD

registerBeanPostProcessors(很重要)

initMessageSource(和国际化有关)

initApplicationEventMulticaster(和事件广播器有关)

会判断BD内有没有applicationEventMulticaster这个bean

如果有就拿到这个bean 赋值给 applicationEventMulticaster这个属性

如果没有 就会默认 给一个SimpleApplicationEventMulticaster,并将这个对象赋给applicationEventMulticaster属性,并将这个bean放到单例池里面

registerListeners();和事件监听器有关

需要程序员自己去 写事件监听器

这个算是 娄底的 如果一个类上面标了 @Lazy 注解 是不会通过 后置处理器的,但是这个类的信息会放到BD里

这个方法会获得 所有的事件监听器(根据类型ApplicationListener,在BD里面获取),然后会将这写事件监听器的beanname放到 SimpleApplicationEventMulticaster这个事件广播器一个属性中(applicationListenerBeans),在事件发布时,就会去getBean方法

问题来了

怎么判断一个bean是不是 事件监听器 

通过BeanPostProcess来完成 之前我们也刚好 放了一个ApplicationListenerDetector这个对象 在prepareBeanFactory这个方法里放的 

ApplicationListenerDetector就会在 初始化后 判断一个bean是不是一个监听器,然后放到事件广播器的一个属性中

我们事件发布都是通过 事件广播器完成的、

事件发布 默认是 广播的

所有的listen都会执行(串行的)

finishBeanFactoryInitialization(beanFactory);

执行到这里,已经完成了bean的扫描,会对我们设置的一些bean,和一些规则,提前搞定,为了实例化单例bena做准备

设置一些类型转换器conversionService

设置 设置默认的占位符解析器 ${xxx} —key

这里设置的就是Lambda表达式 是根据environment来解决的 xxx本来就是 环境变量 的key

最后 创建非懒加载的单例bean

finishRefresh();不太重要

和Spring生命周期有关

会发布一个事件

解析配置类

ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry 方法

获得所有的BD 遍历

得到这些BD中的配置类

配置类的判断

先分析获得这个类 标注的所有注解(注解读取器)

AnnotationMetadata metadata

下来获得 Configuration注解的 key和value

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName())

	if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}
		// 存在@Configuration,并且proxyBeanMethods为false时,是lite配置类
		// 或者不存在@Configuration,但是只要存在@Component、@ComponentScan、@Import、@ImportResource四个中的一个,就是lite配置类
		// 或者不存在@Configuration,只要存在@Bean注解了的方法,就是lite配置类
		else if (config != null || isConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
		}
		else {
			return false;
		}
	// It's a full or lite configuration candidate... Let's determine the order value, if any.
		Integer order = getOrder(metadata);
		if (order != null) {
			beanDef.setAttribute(ORDER_ATTRIBUTE, order);
		}

		return true;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值