- 首先,从一个简单案例说起
- 主配置类
- 测试类
- 测试实体类
- 最主要的代码就是下面这句
- 那么,我们就看看这句话到底干了些什么事情
- 主要分为了以下的三步:
- 一、我们先看第一个: 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();
首先,从一个简单案例说起
主配置类
@Configurationpublic class MainConfig {@Beanpublic 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.internalConfigurationAnnotationProcessororg.springframework.context.event.internalEventListenerFactoryorg.springframework.context.event.internalEventListenerProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.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())// 创建一个集合,用于保存需要处理的beanSet<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() 子流程// 内部再调用parseparse();// 处理 配置类processConfigurationClass(new ConfigurationClass(reader, beanName))// 真正的解析逻辑doProcessConfigurationClass(configClass, sourceClass)// PropertySources 注解的 beanprocessPropertySource(propertySource)// ComponentScans / ComponentScan 注解的 bean// 调用包扫描器进行扫描this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName())// 处理 @Import 进来的processImports(configClass, sourceClass, getImports(sourceClass), true);// 处理 ImportResourceconfigClass.addImportedResource(resolvedResource, readerClass);// 处理 @BeanSet<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) )
// 循环所有后置处理器,调用 postProcessBeanFactorypostProcessor.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 的beanbeanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)// 没有的话,创建一个,将其注册到容器中new DelegatingMessageSource();beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
3.8 initApplicationEventMulticaster(); 创建事件的多播器
// 判断容器中,是否包含 名称为 applicationEventMulticaster 的beanbeanFactory.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()
// 取出那些早期的 ApplicationListenergetApplicationListeners();// 注册到多播器中getApplicationEventMulticaster().addApplicationListener(listener);// 获取所有的 ApplicationListener 类型的beangetBeanNamesForType(ApplicationListener.class, true, false)// 注册到多播器中getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)// 取出所有的早期时间,调用多播器 播一下getApplicationEventMulticaster().multicastEvent(earlyEvent)
3.11 finishBeanFactoryInitialization(beanFactory)
beanFactory.preInstantiateSingletons();// 取出所有的bean定义for (String beanName : beanNames) {// 根据beanName 获取beanDefinitiongetMergedLocalBeanDefinition(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))
