Spring配置Bean加载和SpringBoot自动加载之间的关系

Spring配置Bean加载和SpringBoot自动加载之间的关系

1.ConfigurationClassPostProcessor 的注入和调用

Springboot启动过程

1.context = createApplicationContext();
	1.1 return this.applicationContextFactory.create(this.webApplicationType);
	
2.return new AnnotationConfigServletWebServerApplicationContext();

3.this.reader = new AnnotatedBeanDefinitionReader(this);

4.this(registry, getOrCreateEnvironment(registry));	

5.public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	
	/**
	* 这步为容器注入一个名为
 	* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
 	* 类型为ConfigurationClassPostProcessor.class的bean
	**/
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

ConfigurationClassPostProcessor继承自BeanDefinitionRegistryPostProcessor
Spring容器启动过程中AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);
在这里插入图片描述
因为容器refresh方法之前注册了ConfigurationClassPostProcessor,这里调用BeanDefinitionRegistryPostProcessor后置处理器的接口实现
在这里插入图片描述
在这里插入图片描述
分两步1.解析配置类 2.处理deferImportSelector
在这里插入图片描述
这里对标记传入方法的sourceClass类进行注解解析
其中@ComponentScan会递归调用ConfigurationClassParser.parse方法
代码层面理解就是扫到的配置类上面也可能标注如@Import注解
在这里插入图片描述

解析@Import注解之前 递归调用获取importCandidates
一个AutoConfigurationPackages.Registrar.class
一个AutoConfigurationImportSelector.class
在这里插入图片描述
对应@Import注解Value的三种Value解析
在这里插入图片描述

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered 

AutoConfigurationImportSelector会被放入deferredImportSelectorHandler之后处理

2.SpringBoot自动加载

在这里插入图片描述
上图grouping.getImports()内部调用过程

1.grouping.getImports();

2.this.group.process(deferredImport.getConfigurationClass().getMetadata(),deferredImport.getImportSelector());

//内部调用spring.loaderfactories方法加载
3.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);//将spring.factories结果封装起来

在这里插入图片描述
上图返回spring.factories集合中遍历AutoConfig***类
在放入同样解析@Import注解的processImports方法中处理(spring.factories中的注解都是作为普通Configuration放入容器)
在这里插入图片描述
至此自定义和springboot自动配置的Config加载完成

3.扩展

1.其他后置处理器BeanPostProcessor实现有
BeanValidationPostProcessor
|- JSR-303
AnnotationAwareAspectJAutoProxyCreator
|- AOP 实现接口上层是SmartInstantiationAwareBeanPostProcessor
ConfigurationPropertiesBindingPostProcessor
|-解析@ConfigurationProperties注解

2.DeferredImportSelector接口延后了@Import注解加载的顺序 如晚于当前Config类其他注解之后生效;默认ImportSelector和其他注解一起生效

TODO

1.ConfigurationClassPostProcessor中的BeanFactoryPostProcessor实现中有一行

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	int factoryId = System.identityHashCode(beanFactory);
	if (this.factoriesPostProcessed.contains(factoryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + beanFactory);
	}
	this.factoriesPostProcessed.add(factoryId);
	if (!this.registriesPostProcessed.contains(factoryId)) {
		// BeanDefinitionRegistryPostProcessor hook apparently not supported...
		// Simply call processConfigurationClasses lazily at this point then.
		processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
	}
	
	//todo CGLIB代理 貌似记得SPRING的confg确实都是代理对象 待验证?
	enhanceConfigurationClasses(beanFactory);
	beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
  1. ConfigurationClassParser中的ImportStack
processImports方法中有这样三个操作 数据结构操作 todo目的?
private final ImportStack importStack = new ImportStack();
this.importStack.push(configClass);
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
this.importStack.pop();

关键词:Spring后置处理器,@Import注解,Springboot-autoconfig

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值