通过SpringBoot之Spi机制加载Spring.factories 、SpringBoot之解析启动类源码分析已经得到IOC容器中所有的类的相关信息。
对于用户自定义的类在解析启动类扫描包路径下的过程中就已经完成其AnnotatedGenericBeanDefinition类型的BeanDefinitions的初始化。
public class ConfigurationClassPostProcessor{
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
...
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator,
registry);
do {
//ConfigurationClassParser#parse
parser.parse(candidates);
parser.validate();
...
}
...
this.reader.loadBeanDefinitions(configClasses);
while (!candidates.isEmpty());
}
}
其实就是触发spring.factories文件中自动装配候选类【包含其利用@Bean、@Import等注解再次间接引入的候选类】对应的其BeanDefinitions的初始化,具体如下:
class ConfigurationClassBeanDefinitionReader {
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
}
主要包括四种方式:
- 当前候选类是否被其他类通过@Import注解引入的。绝大部分的候选类满足。
- 当前候选类中利用@Bean注解引入的候选类。
- 当前候选类通过@Import注解引入ImportBeanDefinitionRegistrar类型的候选类。
1.处理ImportBeanDefinitionRegistrar类型的候选类
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
参考@MapperScan引入的MapperScannerRegistrar。
2.处理候选类Bean注解引入的bean信息
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
// 解析当前方法存在的相关Conditional相关的注解
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
...
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
if (metadata.isStatic()) {
// static @Bean method
if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
}
else {
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
}
beanDef.setUniqueFactoryMethodName(methodName);
}
else {
// instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
if (metadata instanceof StandardMethodMetadata) {
beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
}
...
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
...
// 如果@Bean注解的方法满足条件,则将对应bean的定义信息添加到beanDefinitionMap
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
3.BeanDefinition相关概念
BeanDefinition 描述了一个 bean 实例,它记录了bean的属性值、构造函数参数值以及其他更多信息。BeanDefinition在Spring 管理bean中至关重要,指导了Spring 如何依据BeanDefinition生成Bean,bean的作用域,是否懒加载等等。
BeanDefinition中具有设置和获取 此bean 定义的父BeanDefinition的名称(如果有),bean 类名,Bean的作用域,Bean是否懒加载,当前bean依赖的bean名称,是否Autowire候选者,是否是最主要的自动装配候选者,初始化方法名称,销毁方法名称,是否单例,是否原型,bean属性值。
传统的基于XML Spring 容器便是使用对于的BeanDefinitionReader解析XML将xml中的信息包装成BeanDefinition保存到Spring容器中,后续由Spring容器根据BeanDefinition对Bean进行管理。
BeanDefinitionReader:Bean定义信息读取器。BeanDefinitionReader的典型实现莫过于XmlBeanDefinitionReader,它负责解析xml生成BeanDefinition并注册。
BeanDefinitionRegistry:Bean定义注册中心,主要是对BeanDefinition的增删改查,自然内部会对BeanDefinition信息进行存储。
通常情况下使用BeanDefinitionBuilder完成BeanDegination接口相关子类的创建。