创建容器new AnnotationConfigApplicationContext(AppConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用默认无参构造器,里面有一大堆初始化逻辑
this();
//把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
//怎么注册? 委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
// 传入Class 生成 BeanDefinition , 然后通过 注册到 BeanDefinitionRegistry
register(annotatedClasses);
//刷新容器上下文
refresh();
}
在refresh();方法中,执行了invokeBeanFactoryPostProcessors(beanFactory);方法。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors 获取的是 this.beanFactoryPostProcessors;
//this.beanFactoryPostProcessors 只能通过 AbstractApplicationContext.addBeanFactoryPostProcessor 方法添加
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
其中,最主要的是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());。
在该方法中,第一次调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);时调用了ConfigurationClassPostProcessor#processConfigBeanDefinitions方法。
//ConfigurationClassPostProcessor#processConfigBeanDefinitions源码
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
做了两件事情:
this.registriesPostProcessed.add(registryId);将id注册到registriesPostProcessed中- 调用
processConfigBeanDefinitions(registry);方法,解析配置类。
//processConfigBeanDefinitions(registry)方法部分源码
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
...
// 解析配置类
parser.parse(candidates);
...
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
···
// Import类,@Bean,@ImportResource 转化为 BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
...
}
parser.parse(candidates);源码:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 根据不同的 BeanDefinition 实例对象 调用不同的 parse 方法
// 底层其实都是在调用 org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
} else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
//执行DeferredImportSelector
this.deferredImportSelectorHandler.process();
}
parser.parse(candidates);负责解析配置类、解析非延迟加载的Import。
在解析配置类时,也维护了成员变量ConfigurationClassParser#configurationClasses。解析完配置类之后执行DeferredImportSelector(延迟加载大概就是在这里体现的)。
this.reader.loadBeanDefinitions(configClasses);负责将 Import类、@Bean、@ImportResource转化为BeanDefinition。configClasses参数来自ConfigurationClassParser#configurationClasses。
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
public Set<ConfigurationClass> getConfigurationClasses() {
// this.configurationClasses 为ConfigurationClassParser#configurationClasses
return this.configurationClasses.keySet();
}
感谢关注微信公众号: