spring 源码系列(二) spring初始化流程

一、源码分析调试入口

进行spring源码分析时,可以写个测试类,一步一步往下调试

测试类如下:

package com.wangcongming.demo;

import com.wangcongming.demo.config.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @program: spring
 * @description: 测试
 * @author: wang congming
 * @create: 2019-12-10 20:18
 */
public class Test {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
	}
}


package com.wangcongming.demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @program: spring
 * @description:
 * @author: wang congming
 * @create: 2019-12-14 21:12
 */
@Configuration
@ComponentScan("com.wangcongming.demo")
public class AppConfig {

}


package com.wangcongming.demo.service;

import org.springframework.stereotype.Service;

/**
 * @program: spring
 * @description:
 * @author: wang congming
 * @create: 2019-12-11 20:28
 */
@Service
public class UserService {

	public UserService() {
		System.out.println("userService con");
	}

	public void query(){
		System.out.println("query");
	}
}

二、spring 容器以及初始化流程

 

spring 源码系列(二) spring初始化流程_第1张图片

 

import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.PostProcessorRegistrationDelegate;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.ConfigurationClassParser;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.context.annotation.ComponentScanAnnotationParser;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;

//1. spring容器初始化时,会先调用父类的构造方法,实例化一个工厂 DefaultListableBeanFactory
GenericApplicationContext#GenericApplicationContext()
	AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
		2.1 初始化AnnotatedBeanDefinitionReader (bd读取器)
		AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(BeanDefinitionRegistry)
			初始化出一个注册器 (register也是spring环境,相等于AnnotationConfigApplicationContext)
			AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry)
				在给定的注册表中注册所有相关的属性
				1)添加AnnotationAwareOrderComparator的对象,用于排序
				2)添加ContextAnnotationAutowireCandidateResolver对象,用于处理延迟加载
				3)往beanDefinitionMap中注册多个对象,包含(ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor等)
					此处添加的一系列后置处理器,后面会使用到,PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors主要是
					在spring的beanFactory初始化的过程中去做一些事情,怎么来做这些事情呢?委托了多个实现了BeanDefinitionRegistryPostProcessor
					或者BeanFactoryProcessor接口的类来做这些事情,有自定义的也有spring内部的其中ConfigurationClassPostProcessor就是一个
					spring内部的BeanDefinitionRegistryPostProcessor因为如果你不添加这里就没有办法委托ConfigurationClassPostProcessor做一些功能
					
					标记 : A1
				AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry,Object)
					往beanDefinitionMap中注册一个对象
					AnnotationConfigUtils#registerPostProcessor(BeanDefinitionRegistry, RootBeanDefinition, String)
		2.2 初始化ClassPathBeanDefinitionScanner (bean扫描器)   ???? 后面补充
		ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(BeanDefinitionRegistry)
		2.3 注册bean或者注册一个配置类
		此处是一个空壳方法,委托给AnnotatedBeanDefinitionReader注册
		AnnotationConfigApplicationContext#register(Class... componentClasses)
			实际执行注册的方法
			AnnotatedBeanDefinitionReader#register(Class... componentClasses)
				注册,此处就是解析bean,将bean数据放入BeanDefinition中
				1)通过AnnotatedGenericBeanDefinition解析class
				2)解析bean的作用域
				3)根据规则生成bean name
				4)处理类中常用的注解,并将注解信息放入BeanDefinition中
				5)自定义注解解析
				6)代理域的处理 springmvc中使用
				AnnotatedBeanDefinitionReader#doRegisterBean
		2.4 刷新
		AbstractApplicationContext#refresh()
			2.4.1 准备工作,设置启动时间,是否激活标识位,初始化属性源配置
			AbstractApplicationContext#prepareRefresh
			2.4.2 获取一个工厂
			AbstractApplicationContext#obtainFreshBeanFactory
			2.4.3 初始化工厂,准备工厂
			AbstractApplicationContext#prepareBeanFactory
			2.4.4 这里是个空方法, 允许在上下文子类中对bean工厂进行后处理。 
			AbstractApplicationContext#postProcessBeanFactory
			2.4.5 这里就是执行BeanFactoryPostProcessors
			AbstractApplicationContext#invokeBeanFactoryPostProcessors
				2.4.5.1 依次执行BeanFactoryPostProcessors
				1)会将AbstractApplicationContext中beanFactoryPostProcessors list中的数据遍历出来,
					如果是BeanDefinitionRegistryPostProcessor类型,则执行它的postProcessBeanDefinitionRegistry方法
				2)调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors获取到BeanName,根据BeanName去beanDefinitionMap中查找,最终生成对象
				3)调用实现Ordered的BeanDefinitionRegistryPostProcessors。获取到BeanName,根据BeanName去beanDefinitionMap中查找,最终生成对象
				4)调用所有其他BeanDefinitionRegistryPostProcessor(即不符合上述两种情况的),直到全部调用完成
					2) 3) 4) 步骤中的数据即是标记 : A1中添加进beanDefinitionMap中的
				5)执行所有BeanDefinitionRegistryPostProcessors后置处理器中的postProcessBeanFactory方法
				6)执行所有常规BeanFactoryPostProcessors后置处理器中的postProcessBeanFactory方法
				PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory,java.util.List)
					下面简单介绍下上面2)3)4) 中添加的BeanDefinitionRegistryPostProcessors
					2.4.5.1.1     ConfigurationClassPostProcessor 这一块非常重要
						1)从registry(factory)中获得所有BeanDefinitionNames
						2)环境准备、 排序、 bean name生成策略 
						3)解析bean
					ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
						解析bean 这是一个空壳方法 
						ConfigurationClassParser#parse(java.util.Set)
							ConfigurationClassParser#processConfigurationClass(ConfigurationClass)
								1)递归处理内部类 一般很少用到
								2)处理 @PropertySource注解,注入的属性
								3) 处理@ComponentScan 属性
								4)处理其他注解 包含 @Import @ImportResource @Bean 以及接口上的默认方法
								ConfigurationClassParser#doProcessConfigurationClass(ConfigurationClass, SourceClass)
									3)解析扫描包  最终委托给了componentScanParser去完成这件事
									   1. 创建一个扫描器
									   2. 从ComponentScan中获取nameGenerator(bean name生成策略)
									   3. 代理模型 web
									   4. 设置 resourcePattern
									   5. 设置includeFilters excludeFilters
									   6. 设置lazyInit  懒加载
									   7. 处理basePackages
									   8. 使用ClassPathBeanDefinitionScanner扫描包
									ComponentScanAnnotationParser#parse(AnnotationAttributes, final String)
										1) 将扫描到的bean ,存入BeanDefinition 然后放到set中
										2) 遍历set,取出BeanDefinition,进一步处理,之后注册到factory中的BeanDefinitionMap中
										ClassPathBeanDefinitionScanner#doScan(String... basePackages)
											扫描包,并生成BeanDefinition
											ClassPathScanningCandidateComponentProvider#findCandidateComponents
												ClassPathScanningCandidateComponentProvider#scanCandidateComponents
			

 

你可能感兴趣的:(spring源码)