IOC容器启动过程

创建Maven工程用于调试,引入spring-context依赖
IOC容器启动过程_第1张图片
引入配置类,创建一个bean
IOC容器启动过程_第2张图片
定义测试类,new AnnotationConfigApplicationContext(SpringConfig.class)这一句测试代码就可以驱动IoC启动
IOC容器启动过程_第3张图片
仿真进入构造方法

1.调用构造方法

IOC容器启动过程_第4张图片

2.进入this

this()执行之前会先执行父类的构造方法,完成工厂创建
IOC容器启动过程_第5张图片
此时beanFactory已经创建
IOC容器启动过程_第6张图片

1.AnnotatedBeanDefinitionReader

IOC容器启动过程_第7张图片

其逻辑很简单,就是向IoC中注册1个BeanFactoryPostProcessor和4个BeanPostProcessor,Spring就是通过这些PostProcessor扩展点实现对各种注解的解析、处理,让开发只需要简单的几个注解就可以实现很多复杂功能,屏蔽了注解背后处理的复杂逻辑,这也是目前Spring开发趋势:注解驱动开发。
这几个PostProcessor大致作用:

ConfigurationClassPostProcessor:完成@Configuration、@Import、@ComponentScan、@Component、@Bean等注解支持,该类主要完成完成BeanDefinition的采集工作,就是解析各种注解,把需要纳入Spring管理的Bean都采集到一起生成BeanDefinition存储起来,供后续生成对象提供所需的材料;

AutowiredAnnotationBeanPostProcessor:完成@Autowired、@Value注解支持,实现Spring中依赖注入的核心逻辑;

CommonAnnotationBeanPostProcessor:支持JSR-250的一些注解,如:@Resource、@PostConstruct、@PreDestroy等;

EventListenerMethodProcessor和DefaultEventListenerFactory:这两个类主要完成对Spring4.2之后引入的@EventListener等事件注解支持;

上面5个PostProcessor中,最重要的是前两个,一个负责完成从各个地方把需要纳入IoC管理的Bean都收集到一起;另一个则完成对这些收集的Bean进行依赖注入。Spring IoC基本工作就是管理Bean以及依赖注入,所以IoC启动流程分析中,这两个类占有很大的比重。
注册过程:
IOC容器启动过程_第8张图片
IOC容器启动过程_第9张图片
IOC容器启动过程_第10张图片
IOC容器启动过程_第11张图片
AnnotationConfigUtils类的registerAnnotationConfigProcessors方法

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		//这里启动时还没有任何beanDefinition,所以肯定会进入判断
		//internalConfigurationAnnotationProcessor 第一个beanDefinition
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			//加到集合里,这个集合返回了,但是调用的方法也没有用到
			//registerPostProcessor方法把internalConfigurationAnnotationProcessor加到了beanDefinitionMap中
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		//internalAutowiredAnnotationProcessor 第二个beanDefinition
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		//internalCommonAnnotationProcessor 第三个beanDefinition
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		//这个不会进jpaPresent判断不通过
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		//internalEventListenerProcessor 第四个beanDefinition
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}
		//internalEventListenerFactory 第五个beanDefinition
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

AnnotationConfigUtils类的registerPostProcessor方法

	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		//关键方法 registry是AnnotationConfigApplicationContext类型
		//registry是AnnotationConfigApplicationContext类型,会调用父类GenericApplicationContext的registerBeanDefinition方法
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}

GenericApplicationContext的registerBeanDefinition方法
在这里插入图片描述
DefaultListableBeanFactory的registerBeanDefinition方法

	//添加BeanDefinition的原始方法,传入beanName和beanDefinition
	//也就是map的put方法
	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		//一般都会没有,需要添加
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			//判断是不是创建了,一般不会进
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
				//调用map的put方法,将beanDefinition加入到beanDefinitionMap中
				//key是全限定名 value是beanDefinition类型
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//保存名字
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
		//如果当前有这个beandefinition
		if (existingDefinition != null || containsSingleton(beanName)) {
			//重置缓存 启动时不会进入
			resetBeanDefinition(beanName);
		}
	}

2.ClassPathBeanDefinitionScanner

Spring项目中配置或@ComponentScan(basePackages=“a.b.c”),这背后的工作就是靠ClassPathBeanDefinitionScanner完成,其主要就是完成对指定包路径下的Bean进行扫描,把含有特定注解的Bean生成BeanDefinition注册到IoC容器中。
ClassPathBeanDefinitionScanner是Spring中非常重要的一个类,决定了哪些类需要被纳入IoC容器。我们可以继承ClassPathBeanDefinitionScanner实现框架定制化功能,比如MyBatis 的Mapper扫描就是一个典型应用案例,MyBatis 的MapperScannerConfigurer的内部就使用到一个ClassPathBeanDefinitionScanner的子类,实现将Mapper接口文件注入到IoC容器中。
案例:
IOC容器启动过程_第12张图片

注意:AnnotationConfigApplicationContext中定义的:this.scanner = new ClassPathBeanDefinitionScanner(this);,这个其实一般情况下是没有使用的,只有手工调用AnnotationConfigApplicationContext#scan()才会使用到scanner。大部分Bean的采集工作是AnnotatedBeanDefinitionReader中向IoC注册的ConfigurationClassPostProcessor这个BeanFactory后置处理器完成的,它在处理@ComponentScan注解时会重新创建一个ClassPathBeanDefinitionScanner实例,而不是使用AnnotationConfigApplicationContext.scanner这个,这里要特别注意下,避免修改却发现没有起作用的尴尬。

1.@ComponentScan的注册流程

IOC容器启动过程_第13张图片
IOC容器启动过程_第14张图片

1.AbstractApplicationContext类的refresh()方法的invokeBeanFactoryPostProcessors(beanFactory)方法

IOC容器启动过程_第15张图片

2.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法

IOC容器启动过程_第16张图片
IOC容器启动过程_第17张图片

3.ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法

IOC容器启动过程_第18张图片
继续调用ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法
IOC容器启动过程_第19张图片

4.ConfigurationClassParser类的parse方法

IOC容器启动过程_第20张图片
进入parse会继续调用ConfigurationClassParser类的processConfigurationClass方法
在这里插入图片描述

5.ConfigurationClassParser类的processConfigurationClass方法

IOC容器启动过程_第21张图片
ConfigurationClassParser类的doProcessConfigurationClass方法
IOC容器启动过程_第22张图片

6.ComponentScanAnnotationParser类的parse方法
	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
		//这里的scanner就是ClassPathBeanDefinitionScanner类型的了,确实是新建的
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}

		scanner.setResourcePattern(componentScan.getString("resourcePattern"));

		for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addIncludeFilter(typeFilter);
			}
		}
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addExcludeFilter(typeFilter);
			}
		}

		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			Collections.addAll(basePackages, tokenized);
		}
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}

		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});
		//关键方法
		return scanner.doScan(StringUtils.toStringArray(basePackages));
	}
7.ClassPathBeanDefinitionScanner类的doScan方法
	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		//这里是自己配置的@ComponentScan(basePackages = "com.lzp")
		for (String basePackage : basePackages) {
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			//这里能找到两个 Service和TestConfig
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					//关键方法 注册beanDefinition
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

IOC容器启动过程_第23张图片
findCandidateComponents类的findCandidateComponents方法
IOC容器启动过程_第24张图片
IOC容器启动过程_第25张图片
第一个isCandidateComponent
IOC容器启动过程_第26张图片
功能就是找到component类型的注解
第一个循环是排除一些注解的判断,第二个循环是找到component注解
IOC容器启动过程_第27张图片
match方法就是判断当前类是否有xx注解
IOC容器启动过程_第28张图片
this.annotationType.getName()是当前判断的注解,metadataReader.getAnnotationMetadata()是当前类包含的注解,如果两者能匹配就返回true
IOC容器启动过程_第29张图片

isConditionMatch
如果有conponent注解则继续判断,判断你是否有@Conditional注解 , 如果没有就跳过,有的话解析注解,根据条件确定是否加载
IOC容器启动过程_第30张图片

通过后进入第二个isCandidateComponent
isConcrete()判断是不是接口或者抽象类
metadata.isIndependent()判断是否是顶级类或者是内部类
IOC容器启动过程_第31张图片
流程:1.判断是否有@component注解,2.是否有condition条件,3.是否是接口或抽象类
都满足的话进行加载

8.ClassPathBeanDefinitionScanner类的registerBeanDefinition方法

在这里插入图片描述

9.BeanDefinitionReaderUtils类的registerBeanDefinition方法
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//这里就和reader构造中的逻辑一样了
		//registry是AnnotationConfigApplicationContext类型,会调用父类GenericApplicationContext的registerBeanDefinition方法
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//别名
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
10.GenericApplicationContext的registerBeanDefinition方法

IOC容器启动过程_第32张图片

11.DefaultListableBeanFactory的registerBeanDefinition方法(方法详情在AnnotatedBeanDefinitionReader中)

IOC容器启动过程_第33张图片

2.@bean注册流程

1.ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法

对应@ComponentScan的注册流程中的3的第二小步,执行完后执行这个方法,注入config中@bean的实体类
IOC容器启动过程_第34张图片

2.ConfigurationClassBeanDefinitionReader的loadBeanDefinitions方法

IOC容器启动过程_第35张图片

在configurationModel为TestConfig时实现注册
继续ConfigurationClassBeanDefinitionReader类的loadBeanDefinitionsForConfigurationClass方法
IOC容器启动过程_第36张图片
继续本类的loadBeanDefinitionsForBeanMethod方法
方法最后
IOC容器启动过程_第37张图片

3.DefaultListableBeanFactory的registerBeanDefinition方法(方法详情在AnnotatedBeanDefinitionReader中)

IOC容器启动过程_第38张图片

3.构造方法第二个方法:register(componentClasses)

就是将传入的配置类解析成解析成BeanDefinition,注册到IoC容器中,后续ConfigurationClassPostProcessor这个BeanFactory后置处理器在IoC开始真正初始化时,可以获取到这些配置类的BeanDefinition集合,启动解析。
配置类已经加到Map
IOC容器启动过程_第39张图片

4.构造方法第三个方法:refresh

refresh方法定义在AbstractApplicationContext,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作,采用模板模式,定义好IoC启动的流程以及每个步骤的作用,并提供基础实现,其它子类可以重写进行扩展。

1. prepareRefresh();

  • 这一步创建和准备了 Environment 对象,它作为 ApplicationContext 的一个成员变量
  • Environment 对象的作用之一是为后续 @Value,值注入时提供键值
  • Environment 分成三个主要部分
  • systemProperties - 保存 java 环境键值
  • systemEnvironment - 保存系统环境键值
  • 自定义 PropertySource - 保存自定义键值,例如来自于 *.properties 文件的键值
    *IOC容器启动过程_第40张图片

2.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

这一步获取(或创建) BeanFactory,它也是作为 ApplicationContext 的一个成员变量

  • BeanFactory 的作用是负责 bean 的创建、依赖注入和初始化,bean 的各项特征由 BeanDefinition 定义
  • BeanDefinition 作为 bean 的设计蓝图,规定了 bean 的特征,如单例多例、依赖关系、初始销毁方法等
  • BeanDefinition 的来源有多种多样,可以是通过 xml 获得、配置类获得、组件扫描获得,也可以是编程添加
  • 所有的 BeanDefinition 会存入 BeanFactory 中的 beanDefinitionMap 集合
    IOC容器启动过程_第41张图片

两个方法,
IOC容器启动过程_第42张图片
refresh中设置了序列化id
IOC容器启动过程_第43张图片
getBeanFactory会调用父类一开始创建的beanFactory(进入this时创建的)
IOC容器启动过程_第44张图片

3.prepareBeanFactory(beanFactory);

  • 这一步会进一步完善 BeanFactory,为它的各项成员变量赋值
  • beanExpressionResolver 用来解析 SpEL,常见实现为 StandardBeanExpressionResolver
  • propertyEditorRegistrars 会注册类型转换器
  • 它在这里使用了 ResourceEditorRegistrar 实现类
  • 并应用 ApplicationContext 提供的 Environment 完成 ${ } 解析
  • registerResolvableDependency 来注册 beanFactory 以及 ApplicationContext,让它们也能用于依赖注入
  • beanPostProcessors 是 bean 后处理器集合,会工作在 bean 的生命周期各个阶段,此处会添加两个:
  • ApplicationContextAwareProcessor 用来解析 Aware 接口
  • ApplicationListenerDetector 用来识别容器中 ApplicationListener 类型的 bean

IOC容器启动过程_第45张图片
IOC容器启动过程_第46张图片

4.postProcessBeanFactory(beanFactory);

  • 默认空实现,留给子类扩展使用,可以修改beanDefinition信息
  • 可以参照:AbstractRefreshableWebApplicationContext#postProcessBeanFactory()
  • 一般 Web 环境的 ApplicationContext 都要利用它注册新的 Scope,完善 Web 下的 BeanFactory
  • 这里体现的是模板方法设计模式

5.invokeBeanFactoryPostProcessors(beanFactory);

调用BeanFactory后置处理器(包括BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor)
前面巴拉巴拉一大堆,基本还是各种配置、填充工作,这一步就到了IoC容器开始真正干活的阶段了。invokeBeanFactoryPostProcessors(beanFactory)方法主要就是完成对所有注册进来的BeanFactory后置处理器执行调用,包括BeanFactoryPostProcessor及其子类BeanDefinitionRegistryPostProcessor。这里就会有个前面提到的Spring中非常重要的一个类:ConfigurationClassPostProcessor开始被执行,它执行完成后,所有需要Spring管理的Bean都会被解析成BeanDefinition注册进来。@Configuration、@Bean、@Import、@ComponentScan、@Component等等相关配置注解会被处理,相关的Bean也被解析成BeanDefinition注册进来。

  • 这一步会调用 beanFactory 后处理器
  • beanFactory 后处理器,充当 beanFactory 的扩展点,可以用来补充或修改 BeanDefinition
  • 常见的 beanFactory 后处理器有
  • ConfigurationClassPostProcessor – 解析 @Configuration、@Bean、@Import、@PropertySource 等
  • PropertySourcesPlaceHolderConfigurer – 替换 BeanDefinition 中的 ${ }
  • MapperScannerConfigurer – 补充 Mapper 接口对应的 BeanDefinition
    IOC容器启动过程_第47张图片
    经过这个步骤,dog类也被加到了beanDefinitionMap中
    IOC容器启动过程_第48张图片

6.registerBeanPostProcessors(beanFactory);

registerBeanPostProcessors方法主要是将BeanDefinition对应的BeanPostProcessor实例化并通过beanFactory.addBeanPostProcessor()方法注册进来

  • 这一步是继续从 beanFactory 中找出 bean 后处理器,添加至 beanPostProcessors 集合中
  • bean 后处理器,充当 bean 的扩展点,可以工作在 bean 的实例化、依赖注入、初始化阶段,常见的有:
  • AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
  • CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
    IOC容器启动过程_第49张图片
    IOC容器启动过程_第50张图片
    增加了3个
    IOC容器启动过程_第51张图片

7.initMessageSource();

这一步是为 ApplicationContext 添加 messageSource 成员,实现国际化功能

  • 去 beanFactory 内找名为 messageSource 的 bean,如果没有,则提供空的 MessageSource 实现
    IOC容器启动过程_第52张图片

8.initApplicationEventMulticaster();

  • 这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster
  • 它的作用是发布事件给监听器
  • 去 beanFactory 找名为 applicationEventMulticaster 的 bean 作为事件广播器,若没有,会创建默认的事件广播器
  • 之后就可以调用 ApplicationContext.publishEvent(事件对象) 来发布事件
    IOC容器启动过程_第53张图片

9.onRefresh();

  • 这一步是空实现,留给子类扩展
  • SpringBoot 中的子类在这里准备了 WebServer,即内嵌 web 容器
  • 体现的是模板方法设计模式

10. registerListeners();

  • 这一步会从多种途径找到事件监听器,并添加至 applicationEventMulticaster
  • 事件监听器顾名思义,用来接收事件广播器发布的事件,有如下来源
  • 事先编程添加的
  • 来自容器中的 bean
  • 来自于 @EventListener 的解析
  • 要实现事件监听器,只需要实现 ApplicationListener 接口,重写其中 onApplicationEvent(E e) 方法即可
    IOC容器启动过程_第54张图片

11.finishBeanFactoryInitialization(beanFactory);

在执行finishBeanFactoryInitialization(beanFactory); 方法前,所有的配置类都已经变成了 beanDefinition 保存 beanFactory 的 beanDefinitionMap 中。现在执行 finishBeanFactoryInitialization(beanFactory)方法是为了让 所有的 beanDefinition 变成 bean。

大体的流程是:遍历 beanDefinitionMap 中的每一个 beanDefinition,从里面拿出 className,以 className 为依据,去 beanFactory 的 singletonObject 属性中去拿对应名字的 bean。如果能拿到,那就表示该 beanDefinition 已经变成 bean了,否则就用 beanDefinition 创建新 bean 并保存到 singletonObject 中。

  • 这一步会将 beanFactory 的成员补充完毕,并初始化所有非延迟单例 bean
  • conversionService 也是一套转换机制,作为对 PropertyEditor 的补充
  • embeddedValueResolvers 即内嵌值解析器,用来解析 @Value 中的 ${ },借用的是 Environment 的功能
  • singletonObjects 即单例池,缓存所有单例对象
  • 对象的创建都分三个阶段,每一阶段都有不同的 bean 后处理器参与进来,扩展功能
    IOC容器启动过程_第55张图片

关键方法:preInstantiateSingletons

在这里插入图片描述
preInstantiateSingletons方法内部:

1.获取到所有BeanDefinition名称,后面用于遍历处理

IOC容器启动过程_第56张图片

2.遍历每个bean,触发实例化

在这里插入图片描述

3.执行getBean doGetBean

在这里插入图片描述

在这里插入图片描述

4.执行CreateBean

这里基本是实例化我们自己引入的bean,其他的processor之类的,在进入finishBeanFactoryInitialization方法前就已经实例化好了。springboot启动时,web相关的也会提前实例化,在onRefresh()方法。
IOC容器启动过程_第57张图片

5.执行docreateBean

IOC容器启动过程_第58张图片

1.调用无参构造方法通过反射创建对象

IOC容器启动过程_第59张图片

2.createBeanInstance中初始化bean

IOC容器启动过程_第60张图片
然后会调用BeanUtils.instantiateClass初始化bean

mapper接口的初始化( beandefinition的classType为mapperFactoryBean)
docreateBean中initializeBean方法
IOC容器启动过程_第61张图片
执行初始化方法
IOC容器启动过程_第62张图片
mapperFactoryBean的父类SqlSessionDaoSupport的父类DaoSupport实现了InitializingBean接口,所以会调用afterPropertiesSet方法,检查mapper接口是否都加到了configuration中,没加的话进行添加,基本不会用到,在解析mapper.xml文件时已经加完了
IOC容器启动过程_第63张图片
这里还有一个重要方法就是mapperFactoryBean的getObject,创建mapper代理对象的,只有在servcie中注入mapper时才会调用,否者是不会调用的。调用的入口是初始化service时的populateBean方法。

3.populateBean方法

populateBean方法完成依赖注入任务,主要包括三种方式的依赖注入:自动注入、注解注入和PropertyValues注入。
在这里插入图片描述
回调InstantiationAwareBeanPostProcessor#postProcessProperties方法
AutowiredAnnotationBeanPostProcessor,就是在这个方法中完成@Autowired、@Value注解的依赖注入
CommonAnnotationBeanPostProcessor:支持JSR-250的一些注解,如:@Resource、@PostConstruct、@PreDestroy等
IOC容器启动过程_第64张图片
注解方式实现的依赖注入主要借助于MergedBeanDefinitionPostProcessor和InstantiationAwareBeanPostProcessor这两类扩展类实现。比如@Autowired、@Value依赖注入的实现类是AutowiredAnnotationBeanPostProcessor,以及@Resource等JSR-250相关依赖注入的实实现类是CommonAnnotationBeanPostProcessor,他们都实现了MergedBeanDefinitionPostProcessor和InstantiationAwareBeanPostProcessor这两个接口。一般是在MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法中完成注解信息解析,然后缓存到Map等集合中,在InstantiationAwareBeanPostProcessor#postProcessProperties回调方法中,从缓存中查找依赖注入信息,然后进行依赖注入。
最后完成PropertyValues的依赖注入
在这里插入图片描述

4.initMethod方法

IOC容器启动过程_第65张图片
initializeBean()这个方法主要完成Bean的初始化工作,以及在初始化前后都存在BeanPostProcessor扩展点进行方法回调。

IOC容器启动过程_第66张图片

  • @PostConstruct这种比较常用的注解方式,是在InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization方法中被调用的,所以它执行时机是最早的;

  • 实现InitializingBean这种方式次之,具体见invokeInitMethods方法;

  • 最后执行的是@Bean(initMethod = “xxx”)这种方式配置的initMethod; //完成刷新并发布内容
    池中增加了这两个自定义的bean
    IOC容器启动过程_第67张图片

12.finishRefresh();

  • 这一步会为 ApplicationContext 添加 lifecycleProcessor 成员,用来控制容器内需要生命周期管理的 bean
  • 如果容器中有名称为 lifecycleProcessor 的 bean 就用它,否则创建默认的生命周期管理器
  • 准备好生命周期管理器,就可以实现
  • 调用 context 的 start,即可触发所有实现 LifeCycle 接口 bean 的 start
  • 调用 context 的 stop,即可触发所有实现 LifeCycle 接口 bean 的 stop
  • 发布 ContextRefreshed 事件,整个 refresh 执行完成

IOC容器启动过程_第68张图片

整体流程:
1.先初始化,创建AnnotationConfigApplicationContext,传入一个配置类,这个类继承GenericApplicationContext类,GenericApplicationContext继承AbstractApplicationContext类。
2.AnnotationConfigApplicationContext的构造函数又三个方法:this();register(componentClasses);refresh();调用this前会先调用父类的构造函数也就是GenericApplicationContext的构造函数,初始化一个DefaultListableBeanFactory。然后本类的this会初始化AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScannerregister会将第一步传入的配置类变成BeanDefinition。第三个是最关键的方法,在父类的父类AbstractApplicationContext中实现,将所有的bean变成BeanDefinition,然后进行实例化,保存到Context容器中。
3.AbstractApplicationContext类的refresh方法的关键方法invokeBeanFactoryPostProcessors,这个方法会将所有bean变成BeanDefinition,准备实例化。invokeBeanFactoryPostProcessors会调用PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法;
4.invokeBeanFactoryPostProcessors方法中有个关键方法还是PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory)方法,这里方法重载,传参不同。这里会调用当前postProcessor的postProcessBeanFactory(beanFactory)方法,而postProcessor一般会是ConfigurationClassPostProcessor类,postProcessBeanFactory方法会继续调用ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法。
5.关键方法processConfigBeanDefinitions,这里有两个关键方法parser.parse(candidates)this.reader.loadBeanDefinitions(configClasses)
6.关键方法parser.parse(candidates),这里parserConfigurationClassParser类型,candidates是第一步传入的配置类。parse方法有两个关键方法,1是解析componentScancontrollerserviceconfiguration等注解的parse方法(这个parse方法可能会调用其他子类的专门的parse方法,比如ComponentScanAnnotationParser类的parse方法,专门解析componentScan)。2是this.deferredImportSelectorHandler.process(),这个主要用在springboot自动配置,加载其他自动配置类(也就是不在启动类同包下的),获取方式就是META-INF.spring.factories(springboot2.7自动配置不在META-INF下spring.factories文件中而是在
META-INF.spring下的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中),然后放到parserconfigurationClasses属性中,是一个ConfigurationClass类型的set集合,然后由第五步的第二个关键方法变成BeanDefinition
7.关键方法this.reader.loadBeanDefinitions(configClasses),这个readerConfigurationClassPostProcessor类的成员ConfigurationClassBeanDefinitionReader readerconfigClasses就是第六步中第二个关键方法的set集合。这个方法主要是将@bean(loadBeanDefinitionsForBeanMethod(beanMethod)方法),@import(registerBeanDefinitionForImportedConfigurationClass(configClass)方法)修饰的类变成BeanDefinition,同时像mybatismapperscanmapper注解这样的实现了ImportBeanDefinitionRegistrar接口的类,也通过这个方法变成BeanDefinition(loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars())方法)。springboot最关键的自动配置功能,就是这个方法实现的,xxxAutoConfiguration类都是在这里变成的BeanDefinition(在parser.parse方法中找到所有自动配置类,然后在this.reader.loadBeanDefinitions方法中将配置类连同配置类中引入的bean一起加到BeanDefinition)。

参考链接:https://baijiahao.baidu.com/s?id=1724327365978008424&wfr=spider&for=pc
https://www.bilibili.com/read/cv5637654?spm_id_from=333.999.0.0

你可能感兴趣的:(Spring,java,spring)