前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring源码篇(五)启动过程

spring源码篇(五)启动过程

作者头像
用针戳左手中指指头
修改2023-10-24 18:46:37
5280
修改2023-10-24 18:46:37
举报
文章被收录于专栏:学习计划学习计划

前言

前面我们了解了bean的实例化过程,依赖注入,大体上对一个bean的创建有了认知,那么现在从spring启动来看它的一个架构,本来是想把配置类扫描的也加载本章,但两个主题并不相同,就拆开了。

  1. 为什么spring要启动?
  2. spring启动又做了什么?

源码流程

按惯例,还是从源码走一遍,熟悉流程。

1. 启动applicationContext

AnnotatedBeanDefinitionReader它自己继承自BeanDefinitionRegistry,还继承了GenericApplicationContext,并且,在构造方法中默认创建一个beanFactory,所以AnnotationConfigApplicationContext在实例化时,就会执行父类的构造方法,创建一个beanFactory

image-20210304234809219
image-20210304234809219

AnnotationConfigApplicationContext实例化

代码语言:javascript
复制
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		// 1. 创建BeanFactory
		// 2. 生成AnnotatedBeanDefinitionReader
		// 3. 生成ClassPathBeanDefinitionScanner
		this();

		// 利用reader把componentClasses(我们的配置类)注册为一个BeanDefinition
		register(componentClasses);

		// 调用AbstractApplicationContext的refresh()方法,模板模式,会启动ApplicationContext
		// 为什么叫refresh,而不叫start?
		refresh();
	}

this()方法进入,在里面的找到下面的代码。

AnnotatedBeanDefinitionReader和beanDefinition篇章提到过的reader是一样的,都可以生成beanDefinition。

代码语言:javascript
复制
public AnnotationConfigApplicationContext() {
		// 在执行这个构造方法之前,会先执行父类的构造方法,会初始化一个beanFactory = new DefaultListableBeanFactory()

		// 生成并注册5个BeanDefinition
		// 1.ConfigurationClassPostProcessor
		// 2.AutowiredAnnotationBeanPostProcessor
		// 3.CommonAnnotationBeanPostProcessor
		// 4.EventListenerMethodProcessor
		// 5.DefaultEventListenerFactory
		this.reader = new AnnotatedBeanDefinitionReader(this);

		// 加载环境变量、设置资源加载器、 注册默认的includeFilter
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

AnnotatedBeanDefinitionReader往里走,它在这个方法里进行5个beanDefinition的注册,代码在

AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

这5个中,也有我们熟悉的,如:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,他们是解析注解的处理器,上一篇篇章我们的依赖注入就是在这两个中实现的。

ConfigurationClassPostProcessord这个是配置类的后置处理器,后面我们的配置类扫描是在它里面实现的。

其他的先忽略。

而后进入:

代码语言:javascript
复制
register(componentClasses);

componentClasses是我们的配置类,按照方法名去看,它是把我们的配置类,解析成beanDefinition注册到容器(beanFactory)里了,那到底是不是这样呢?看最底层的代码:

代码语言:javascript
复制
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

		// 直接生成一个AnnotatedGenericBeanDefinition
    // 这里做了两个操作:1.设置beanClass = 我们传进去的class, 2. 解析元数据(metaData)
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		// 判断当前abd是否被标注了@Conditional注解,并判断是否符合所指定的条件,如果不符合,则跳过,不进行注册
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		// 设置supplier、scope属性,以及得到beanName
		abd.setInstanceSupplier(supplier);
		// @Scope注解的元数据信息
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		// 获取Lazy、Primary、DependsOn、Role、Description注解信息并设置给abd
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		// 使用自定义器修改BeanDefinition
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}

		// BeanDefinition中是没有beanName的,BeanDefinitionHolder中持有了BeanDefinition,beanName,alias
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

		// 解析Scope中的ProxyMode属性,默认为no,不生成代理对象
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

		// 注册到registry中
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

在生成AnnotatedGenericBeanDefinition时,它直接就赋值了beanClass,但是在扫描bean那个阶段,它是ASM解析的,是没有加载类class的,所以在那个阶段就先设置了类名,不像这里,这里是直接传入了我们的class对象,是已经指定好的。

然后再生成BeanDefinitionHolder,然后添加到beanDefinitionMap中去(注册)。

refresh方法

进入refresh方法:

代码语言:javascript
复制
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 刷新前处理;环境配置加载,必要属性验证等
			prepareRefresh();

			// 刷新beanFactory,并获取一个空的beanFactory,
            // 这时的beanFactory有6个beanDefinition,5个默认的,1个我们的配置类
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  

			// 准备BeanFactory
			// 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
			// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
			// 3. 记录ignoreDependencyInterface
			// 4. 记录ResolvableDependency
			// 5. 添加三个单例Bean
			prepareBeanFactory(beanFactory);

			try {
				// 子类可以对BeanFactory进行进一步初始化;添加beanFactory的后置处理器
				postProcessBeanFactory(beanFactory);

				// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
				// 默认情况下:
				// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
				// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
				// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
				// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
				invokeBeanFactoryPostProcessors(beanFactory);  //BeanDefinitionRegistryPostProcessor ,BeanFactoryPostProcessors

				// 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中
				registerBeanPostProcessors(beanFactory);

				// 初始化MessageSource,如果配置了一个名字叫做“messageSource”的BeanDefinition
				// 就会把这个Bean创建出来,并赋值给ApplicationContext的messageSource属性
				// 这样ApplicationContext就可以使用国际化的功能了
				initMessageSource();

				// 设置ApplicationContext的applicationEventMulticaster
				initApplicationEventMulticaster();

				// 执行子类的onRefresh方法
				onRefresh();

				// 注册Listener
				registerListeners();

				// 完成beanFactory的初始化(实例化非懒加载的单例bean)
				finishBeanFactoryInitialization(beanFactory);

				// 发布事件
				finishRefresh();
			}

			catch (BeansException ex) {
				// 省略。。。
			}

			finally {
				
				resetCommonCaches();
			}
		}
	}
prepareBeanFactory

准备beanFactory阶段,需要加载一些

代码语言:javascript
复制
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
    // 设置表达式解析器
		beanFactory.setBeanExpressionResolver(new  StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 注册类型转化器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// bean工厂的后置处理器;设置容器中的bean的属性,这里是设置一些内部的bean
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

		// 如果一个属性对应的set方法在ignoredDependencyInterfaces接口中被定义了,则该属性不会进行自动注入(是Spring中的自动注入,不是@Autowired)
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// 相当于直接把ApplicationContext对象放入Bean工厂中,当getBean(type)时,如果type就是这四个type,则直接返回所设置的实例
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// bean工厂后置处理器;用于发布监听器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			//跟aop有关系
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 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());
		}
	}

这个prepareBeanFactory方法,是在未beanFactory做准备,做了这么些事:

  1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
  2. 添加三个BeanPostProcessor:ApplicationContextAwareProcessor、ApplicationListenerDetector、LoadTimeWeaverAwareProcessor
  3. 记录ignoreDependencyInterface
  4. 记录ResolvableDependency:就是把applicationContext对象放到bean工厂,有4个:beanFactory、resourceLoader、applicationEventpublisher、applicationContext
  5. 添加3个单例bean:environment、systemProperties、systemEvironment

所以一般情况下,到这一步,bean工厂中只有2个后置处理器,3个单例,4个内置对象、6个beanDefinition

invokeBeanFactoryPostProcessors

接着上一个方法,

步骤1:手动的后置处理器处理
代码语言:javascript
复制
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 看这段,下面的不看
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 关于LoadTimeWeaver看这篇文章了解即可,https://www.cnblogs.com/wade-luffy/p/6073702.html
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

这个方法中有一个getBeanFactoryPostProcessors获取bean工厂的后置处理器,一般情况下这里是空的,因为到这一步,还没有注册bean工厂的后置处理器,但如果我们手动注册一个的话,这里就会拿到了。

比如:实现了BeanFactoryPostProcessor接口,就会被找到。

而如果是实现了BeanFactoryPostProcessor接口下的子接口BeanDefinitionRegistryPostProcessor他会去强转,因为功能不一样了,BeanDefinitionRegistryPostProcessor是带有注册功能的。如下:

代码语言:javascript
复制
// 进入方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
代码语言:javascript
复制
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// BeanDefinitionRegistryPostProcessor是一个特殊的BeanFactoryPostProcessor,需要先执行postProcessBeanDefinitionRegistry方法
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;

					registryProcessor.postProcessBeanDefinitionRegistry(registry);

					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

所以上面这一步是执行我们从applicationContext添加进来的beanDefinitionRegisterPosrtProcessor的postProcessBeanDefinitionRegistry

步骤2:找实现了PriorityOrdered的处理器
代码语言:javascript
复制
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 筛选
			for (String ppName : postProcessorNames) {
				// 判断这个类是否还实现了PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
					// 调用getBean的时候,会添加到单例池中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 已添加的列表
					processedBeans.add(ppName);
				}
			}
// 利用已经注册到beanFactory的比较器,对筛选出的后置处理器进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
// 然后再添加到最外层的集合中
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行currentRegistryProcessors中的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空,待下一个逻辑使用
			currentRegistryProcessors.clear();

这一步,它会先找到实现了BeanDefinitionRegistryPostProcessor接口的处理器,然后再找到实现了PriorityOrdered接口的,最后执行postProcessBeanDefinitionRegistry

在这一步,它就会去拿ConfigurationClassPostProcessor,因为它实现了PriorityOrdered接口,所以在这一步,他就会把ConfigurationClassPostProcessor实例化,生成单例。

然后在这里他会执行postProcessBeanDefinitionRegistry后,会去查找配置类,然后将配置类注册为beanDefinition,具体的详细会在后面一篇说明。

步骤3:找实现了ordered的处理器
代码语言:javascript
复制
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

这一步和上面那一步类似,区别是,这里找的是现实了Ordered接口的BeanDefinitionRegistryPostProcessor

步骤4:执行没有执行过的处理器
代码语言:javascript
复制
boolean reiterate = true;
			// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
			// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
			while (reiterate) {
				reiterate = false;
				// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

这一段是为了执行普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法;

这段意思是,一个BeanDefinitionRegistryPostProcessor也可以注册到另一个BeanDefinitionRegistryPostProcessor,所以这里一个循环将所有的BeanDefinitionRegistryPostProcessor都互相注册,比如有BeanDefinitionRegistryPostProcessor:A B C D ,然后走这个循环,第一遍while循环后,有A B C D ,第二遍时再获取一次BeanDefinitionRegistryPostProcessor,这时可能就不至 A B C D ,还可能有 E F G,那么,就还会遍历,如果while循环中新的遍历中都没有新增的BeanDefinitionRegistryPostProcessor,就会结束循环。

而且这里执行是,上面步骤没有执行过的postProcessor,所以,不管你实现了Ordered、还是PriorityOrdered,都会执行;相当于是除去上面步骤没执行的,在这里都执行。

步骤5:执行postProcessBeanFactory

上面步骤执行完postProcessBeanDefinitionRegistry方法后,再执行postProcessBeanFactory方法,这个方法是BeanFactoryPostProcessor类的方法。

代码语言:javascript
复制
			// 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法后,
			// 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

			// 执行手动添加的非BeanDefinitionRegistryPostProcessor类型的Bean工厂后置处理器的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

上面这些步骤,就是为了保证postProcessBeanFactory方法在最后执行;在这一步之前都是执行postProcessBeanDefinitionRegistry方法。

对上面步骤总结一下:

  1. 按顺序找BeanDefinition的处理器,
  2. 然后执行postProcessBeanDefinitionRegistry,注册beanDefinition

上面的步骤中,一般只有一个ConfigurationClassPostProcessor处理器,因为它是默认添加的(在一开始构造器添加的),所以,上面的步骤相当于是在执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法。

步骤6:对beanFactory设置

而下面这段,它是找的BeanFactoryPostProcessor的bean,和上面找的BeanDefinitionRegistryPostProcessor是一样的。

代码语言:javascript
复制
String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		// 默认情况下会拿到两个,一个就是ConfigurationClassPostProcessor,一个就是EventListenerMethodProcessor
		// 保存直接实现了BeanFactoryPostProcessor接口和PriorityOrdered接口的后置处理器
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口和Ordered接口的后置处理器
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口的后置处理器,不包括那些实现了排序接口的类
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 把所有BeanFactoryPostProcessor进行分类
		for (String ppName : postProcessorNames) {
			// 拿到的BeanFactoryPostProcessor包括了BeanDefinitionRegistryPostProcessor,所以要跳过
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 再执行实现了Ordered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后执行普通的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

那么invokeBeanFactoryPostProcessors这个方法大概是:

  1. 执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,注册beanDefinition
  2. 执行ConfigurationClassPostProcessor的postProcessBeanFactory方法,完善BeanFactory
finishBeanFactoryInitialization
代码语言:javascript
复制
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

		// 如果BeanFactory中存在ConversionService,则设置BeanFactory的ConversionService属性
		// ConversionService是用来进行类型转化的
		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));
		}
		// 占位符填充解析器
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}


		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);

		// 冻结所有已经注册了的BeanDefinition,后续不能被修改和处理
		beanFactory.freezeConfiguration();

		// 实例化所有非懒加载的bean
		beanFactory.preInstantiateSingletons();
	}

后面就到了bean的初始化过程。

lifecycle生命周期回调

完成启动时,会去调用lifeCycle类,从代码看,我们只要实现Lifecycle接口,就可以在spring启动完成时执行回调。这个在应用篇有过例子,这里不写了。

代码语言:javascript
复制
// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		// 默认调用DefaultLifecycleProcessor的onRefresh方法
		// 找出Lifecycle Bean执行start方法,默认情况下是没有Lifecycle Bean的,需要自己定义
		getLifecycleProcessor().onRefresh();
代码语言:javascript
复制
@Override
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}

	@Override
	public void onClose() {
		stopBeans();
		this.running = false;
	}

	@Override
	public boolean isRunning() {
		return this.running;
	}


	// Internal helpers

	private void startBeans(boolean autoStartupOnly) {
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new HashMap<>();
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			List<Integer> keys = new ArrayList<>(phases.keySet());
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}

总结

为什么spring要启动?

容器准备,为了能够更方便使用applicationContext。

spring启动又做了什么?

在spring容器启动时,

  1. 创建beanFactory,用于管理bean
  2. 创建beanDefinition读取器,用于读取class
  3. 创建扫描器,加载环境,资源和component的过滤器
  4. 将我们的配置类加载为一个bean定义(beanDefinition)
  5. (refresh方法)环境配置、必要属性设置
  6. 刷新beanFactory
  7. 设置beanFactory:
    1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
    2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
    3. 记录ignoreDependencyInterface
    4. 记录ResolvableDependency
    5. 添加三个单例Bean
  8. 子类对beanFactory设置
  9. 手动后置处理器处理
  10. 执行后置处理器的postProcessBeanDefinitionRegistry方法(实现了优先级、排序接口的)
    1. 配置类扫描
    2. 排序和名称生成器设置
    3. 解析配置类
      1. 找@component注解的类
      2. 解析@propertySource
      3. 解析@componentScan
      4. 解析@Import注解
      5. 解析@ImportSource注解
      6. 解析@Bean标注的方法
  11. 执行postProcessBeanFactory方法
  12. beanFactory后置处理设置beanFactory
  13. 注册bean后置处理器
  14. 初始化国际化资源对象messagesource
  15. 初始化事件发布器
  16. 注册监听器
  17. 实例化非懒加载bean,这里和之前的bean的生命周期接上了。
  18. 生命周期回调接口执行.onfresh
  19. 启动完成发布事件;

我们的配置类在哪一步执行

在执行beanFactory后置处理器时进行扫描的,执行的是ConfigurationClassPostProcessor,会先去扫描我们的配置类,4个注解表示是配置类:Component、componentScan、Import、ImportResource、configuration,这时扫描得到的是beanDefinition。

监听器用来干什么的?

监听容器创建,销毁,从而执行一些初始化加载配置文件的操作

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 源码流程
    • 1. 启动applicationContext
      • refresh方法
    • lifecycle生命周期回调
    • 总结
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档