- 首先,从一个简单案例说起
- 主配置类
- 测试类
- 测试实体类
- 最主要的代码就是下面这句
- 那么,我们就看看这句话到底干了些什么事情
- 主要分为了以下的三步:
- 一、我们先看第一个: this()
- 第一步的流程就分析的差不多了,紧接着看第二步干了什么?
- 二、register(annotatedClasses);
- 三、refresh(); 大名鼎鼎的refresh(),总共分为12步,且听下面一步步分析
- 3.1 prepareRefresh(); 准备刷新阶段
- 3.2 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 获取刷新的Bean工厂
- 3.3 prepareBeanFactory(beanFactory); 对bean工厂进行一些准备(设置bean工厂的类加载器,表达式解析器,后置处理器等等)
- 3.4 postProcessBeanFactory(beanFactory); 对bean工厂进行后置处理,进行一些扫尾工作。这边交由子类去实现,这边是个空方法。
- 3.5 invokeBeanFactoryPostProcessors(beanFactory); 调用bean工厂的后置处理器
- 3.6registerBeanPostProcessors(beanFactory) 注册 bean的后置处理器
- 3.7 initMessageSource()
- 3.8 initApplicationEventMulticaster(); 创建事件的多播器
- 3.9 onRefresh() 注解版的ApplicationContext 是个空方法,交由子类去实现,在SpringBoot中通过这个方法来启动tomcat
- 3.10 registerListeners()
- 3.11 finishBeanFactoryInitialization(beanFactory)
- 3.12 finishRefresh();
首先,从一个简单案例说起
主配置类
@Configuration
public class MainConfig {
@Bean
public Person person() {
return new Person();
}
}
测试类
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println(applicationContext.getBean("person"));
测试实体类
public class Person {
}
最主要的代码就是下面这句
new AnnotationConfigApplicationContext(MainConfig.class);
那么,我们就看看这句话到底干了些什么事情
主要分为了以下的三步:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
一、我们先看第一个: this()
主要分为两步,注册注解的扫描器,以及类路径的扫描器
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
1.1 super() 调用父类的构造函数(主要工作,创建bean工厂,默认是DefaultListableBeanFactory)
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
1.2 new AnnotatedBeanDefinitionReader(this); 注册注解的扫描器
# 主要调用流程
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
registerAnnotationConfigProcessors(registry, null);
# 最主要的工作,往容器中添加了一堆后置处理器,添加对一些技术 (JPA) 的支持
# 主要往容器中添加了如下的几个类型的组件
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.event.internalEventListenerFactory
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
1.3 new ClassPathBeanDefinitionScanner(this); 初始化类路径下的包扫描器
注册添加过滤规则,添加环境,以及资源的加载器
这里的userDefaultFilters,就是我们在 @ComponentScan(useDefaultFilters = false) 中指定的这个属性,用于让其看是否需要使用默认的过滤规则。
默认的扫描规则是,只要是@Component 就扫描进去
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
第一步的流程就分析的差不多了,紧接着看第二步干了什么?
二、register(annotatedClasses);
# 调用上一步的注解扫描器
this.reader.register(annotatedClasses);
# 循环所有传入的配置类,调用registerBean将配置类注册到容器中
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
三、refresh(); 大名鼎鼎的refresh(),总共分为12步,且听下面一步步分析
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
}
}
3.1 prepareRefresh(); 准备刷新阶段
3.1.1 设置容器的一些状态
this.closed.set(false);
this.active.set(true);
3.1.2 初始化一些属性
initPropertySources();
getEnvironment().validateRequiredProperties();
3.1.3 初始化早期事件,早期对象的存放变量,用于存放ApplicationListener,ApplicationEvent
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
3.2 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 获取刷新的Bean工厂
分为两步:
3.2.1 refreshBeanFactory(); 在 GenericApplicationContext 中进行实现,主要工作为,给bean工厂设置一个序列化id,并通过CAS设置refreshed为true,防止并发
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
3.2.2 getBeanFactory() 获取bean工厂 ,在 GenericApplicationContext 中实现,直接返回 在1.1 步中 初始化的 DefaultListableBeanFactory
3.3 prepareBeanFactory(beanFactory); 对bean工厂进行一些准备(设置bean工厂的类加载器,表达式解析器,后置处理器等等)
3.4 postProcessBeanFactory(beanFactory); 对bean工厂进行后置处理,进行一些扫尾工作。这边交由子类去实现,这边是个空方法。
3.5 invokeBeanFactoryPostProcessors(beanFactory); 调用bean工厂的后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
// 创建一个集合,用于保存需要处理的bean
Set<String> processedBeans = new HashSet<>();
// 如果 beanFactory 是 BeanDefinitionRegistry 类型的,很不巧,DefaultListableBeanFactory 就是这个类型的
if (beanFactory instanceof BeanDefinitionRegistry) {
// 循环所有的后置处理器,这些后置处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//区分出两种不同的PostProcessor
}
}
// 根据 PriorityOrdered,Ordered 或者没有标注任何注解的后置处理器,将其保存到不同的集合中
// 然后开始调用这些后置处理器,这个逻辑有点多,在下一步讲
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
// 处理完 BeanDefinitionRegistryPostProcessor 这个类型的后置处理器之后,再处理非这个类型的,
// 也就是 BeanFactoryPostProcessor 这个类型的后置处理器
// 同样,根据 PriorityOrdered,Ordered 或者没有标注任何注解的后置处理器,保存到不同的集合
// 保存完成之后,分别调用这个后置处理器
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
}
以上就是3.5的逻辑步骤,下面再讲讲,BeanDefinitionRegistryPostProcessor 的 invoke 和 BeanFactoryPostProcessor 的invoke如何执行的
BeanDefinitionRegistryPostProcessor 的 invoke(invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry))
//循环所有的 BeanDefinitionRegistryPostProcessor,调用 postProcessBeanDefinitionRegistry方法,
// 实现了 BeanDefinitionRegistryPostProcessor 的后置处理器,可以在对 beanDefinition 进行一些操作,
// 比如修改bean的Class,修改bean初始化调用时的构造函数等等等,(即可以实现偷天换日!)
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
// 默认在Spring中呢,有 ConfigurationClassPostProcessor 这么一个后置处理器,实现了这个接口
// 那么就会调用到这个类的 postProcessBeanDefinitionRegistry方法
// 在这个类中,真正的逻辑都在这个方法中,这个方法就开始真正的解析beanDefinition了
processConfigBeanDefinitions(registry);
// 1. 获取现在所有的beanDefinition,开始循环
registry.getBeanDefinitionNames()
// 如果这个类有@Configuration注解的话
ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
// 将配置类保存起来
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
// 将bean名称的生成器,保存到这个类的属性中
this.componentScanBeanNameGenerator = generator;
//设置@Import导入进来的bean的名称生成器
this.importBeanNameGenerator = generator;
// 创建一个 @Configuration 配置类的解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 开始进行配置类的解析
parser.parse(candidates)
//parser.parse() 子流程
// 内部再调用parse
parse();
// 处理 配置类
processConfigurationClass(new ConfigurationClass(reader, beanName))
// 真正的解析逻辑
doProcessConfigurationClass(configClass, sourceClass)
// PropertySources 注解的 bean
processPropertySource(propertySource)
// ComponentScans / ComponentScan 注解的 bean
// 调用包扫描器进行扫描
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName())
// 处理 @Import 进来的
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理 ImportResource
configClass.addImportedResource(resolvedResource, readerClass);
// 处理 @Bean
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
// 把解析出来的 @Bean @Import 都给注册到容器中了
this.reader.loadBeanDefinitions(configClasses)
// loadBeanDefinitions 子流程
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator)
// 判断这个类是否是Import进来的
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 通过 @Configuration + @Bean进来的
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 通过 @ImportResources 进来的
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 通过 某个类实现了 ImportBeanDefinitionRegistrar 导入进来的
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
//loadBeanDefinitions 结束
BeanFactoryPostProcessor 的 invoke( invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory) )
// 循环所有后置处理器,调用 postProcessBeanFactory
postProcessor.postProcessBeanFactory(beanFactory);
// 假设自己实现了一个 BeanFactoryPostProcessor ,在这步中,就调用 postProcessBeanFactory方法了
3.6registerBeanPostProcessors(beanFactory) 注册 bean的后置处理器
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
// 获取所有的 BeanPostProcessor类型的
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 根据 PriorityOrdered,Ordered,和没有注解三种的后置处理器,分别注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
3.7 initMessageSource()
// 判断容器中是否包含名称为 messageSource 的bean
beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)
// 没有的话,创建一个,将其注册到容器中
new DelegatingMessageSource();
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
3.8 initApplicationEventMulticaster(); 创建事件的多播器
// 判断容器中,是否包含 名称为 applicationEventMulticaster 的bean
beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
// 如果有,取出来赋值给属性 applicationEventMulticaster
// 如果没有,创建一个 SimpleApplicationEventMulticaster 赋值给 applicationEventMulticaster,并注册到容器中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
3.9 onRefresh() 注解版的ApplicationContext 是个空方法,交由子类去实现,在SpringBoot中通过这个方法来启动tomcat
3.10 registerListeners()
// 取出那些早期的 ApplicationListener
getApplicationListeners();
// 注册到多播器中
getApplicationEventMulticaster().addApplicationListener(listener);
// 获取所有的 ApplicationListener 类型的bean
getBeanNamesForType(ApplicationListener.class, true, false)
// 注册到多播器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
// 取出所有的早期时间,调用多播器 播一下
getApplicationEventMulticaster().multicastEvent(earlyEvent)
3.11 finishBeanFactoryInitialization(beanFactory)
beanFactory.preInstantiateSingletons();
// 取出所有的bean定义
for (String beanName : beanNames) {
// 根据beanName 获取beanDefinition
getMergedLocalBeanDefinition(beanName);
// 判断 bean定义
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果不是抽象的 且 是单例的 且 不是懒加载的
if (isFactoryBean(beanName)) {
//如果是 工厂bean,加上 FactoryBean 的特有前缀 & 去进行bean的创建
getBean(FACTORY_BEAN_PREFIX + beanName)
// 然后再去通过getBean 去拿真正的bean
// 实际,会调用到FactoryBean 的 getObject方法
getBean(beanName);
}else {
//不是工厂bean,直接走getBean的流程
getBean();
}
}
}
3.12 finishRefresh();
// 初始化 生命周期 处理器
initLifecycleProcessor();
// 调用LifeCycle 的 onRefresh 方法
getLifecycleProcessor().onRefresh();
// 发布一个容器已经刷新完成的事件,通知观察者
publishEvent(new ContextRefreshedEvent(this))