前言
上一節中簡要說明了下springboot自動化配置的關鍵,那么本節看下springboot真正的初始化過程,如何創建上下文並解析配置,加載我們注冊到容器管理中的類。上節已經成功的創建了SpringApplication,那我們就看下其run方法究竟做了些什么
正文
我們從SpringApplication的run方法開始入手,只看核心代碼,其他省略
public ConfigurableApplicationContext run(String... args) { ...//省略代碼 //聲明spring上下文 ConfigurableApplicationContext context = null; try { ..//省略代碼 //2.新建應用上下文 context = createApplicationContext(); ..//省略代碼 //3.刷新上下文 refreshContext(context); //4.完成刷新上下文后調用(目前空白) afterRefresh(context, applicationArguments); ..//省略代碼 } return context; }
通過上面我們可以發現,run方法核心步驟就是創建ApplicatonContext,這兒主要的步驟有兩個 1.創建應用上下文 2.刷新上下文。我們從創建開始看
1.創建spring的核心 ApplicationContext
查看createApplicationContext方法
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.boot." + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: //我們使用這個 contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } ..//省略 } //反射生成實例 return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }
這兒其實看着是很簡單的邏輯,就是根據類型,選擇與一個合適的創建,這兒我們就用常見的servlet來說明。servlet對應的上下文為AnnotationConfigServletWebServerApplicationContext。然后最后會根據反射來生成一個實例並返回。我們可以看下這個上下文的類圖
相信這個類繼承結構大家都看着比較頭痛,畢竟作為核心類。這兒就挑兩個個重要的說下。
第一。 其最終實現了BeanFactory接口,並繼承了GenericApplicationContext。並且我們查看其構造函數會傳入一個BeanFactory
public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) { super(beanFactory); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
最終在GenericApplicationContext中有如下代碼
private final DefaultListableBeanFactory beanFactory; public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); } public GenericApplicationContext(DefaultListableBeanFactory beanFactory) { Assert.notNull(beanFactory, "BeanFactory must not be null"); this.beanFactory = beanFactory; }
會發現上下文不論如何都會持有一個beanFactory,很多人被問到過ApplicationContext和beanFactory的區別與聯系。其實這兒就能看出來是一個很典型的靜態代理的案例。既然是代理,就說明了肯定ApplicationContext在保持Beanfactory的原有功能時又擴展了很多功能。這樣就可以做到既兼容舊版本,又增強很多功能。當然了,具體的區別有興趣的可以去看下二者的源代碼。
第二。我們在AnnotationConfigServletWebServerApplicationContext的構造函數中發現了有如下步驟
this.reader = new AnnotatedBeanDefinitionReader(this);
這兒新建了一個注解bean的解析器。我們一路跟着源碼看下
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); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
這兒我們會發現該方法最后會為registry注冊一些解析器,我們看下AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);該方法會為Beanfactory設置一系列的BeanDefinition,以及其他的一些東西,
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4); // 處理@Configuration @ComponentScans @Component @Bean等注解 @PropertySources @ImportResource 等 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 處理 @Autowired @Value 等 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 處理@Required @ if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 處理類似@PostConstruct 和@PreDestroy if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 如果有jpa的話這里有處理的 例如@Selevt if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 處理類似@EventListener的注解 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
可以發現這兒設置了很多BeanDefinition,尤其是是ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor這兩可以說是相當核心的兩個后置處理器,在后面spring進行配置解析的時候會相當的有用。
到此,創建ApplicationContext就完成了,我們看系統刷新上下文的時候做了些什么
2. refreshContext spring的核心加載方法
該方法可以說占據了springboot啟動的絕大部分時間,也是springboot啟動中最為核心的方法。
private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } }
protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); }
跟着代碼一路走,發現其最終調用的是上下文的refresh方法。由於其被強轉為AbstractApplicationContext,所以我們直接看其refresh方法,到此就進入ApplicationContext類中了。
3.ApplicationContext中refresh方法
該方法里面有很多初始化方法,我們也選擇核心的說明
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //初始化之前的一些准備,例如設置開始標記等 prepareRefresh(); // 獲取到上面提到的beanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 初始注冊一些要用到的類 prepareBeanFactory(beanFactory); try { // 添加一些BeanFactory的postProcess postProcessBeanFactory(beanFactory); // 執行BeanFactory的PostProcessors invokeBeanFactoryPostProcessors(beanFactory); // 注冊一些BeanPostProcessors registerBeanPostProcessors(beanFactory); ../略過 // 一些特殊的操作,例如 //本案例中是AnnotationConfigServletWebServerApplicationContext 那么這兒會開始創建servlet容器 onRefresh(); ../略過 // 實例化容器中未設置懶加載的類 finishBeanFactoryInitialization(beanFactory); ../略過 } } }
這兒我們我們主要看兩個方法 一是invokeBeanFactoryPostProcessors,該方法會找出所有需要加載的bean。然后是finishBeanFactoryInitialization方法,該方法會將需要加載的bean進行實例化並裝載屬性。
4.invokeBeanFactoryPostProcessors方法
該方法我們跟着源代碼走,最終會走到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,由於該方法過長。所以我們分段說明
4.1 無所不在的PostProcesser
不得不說spring將切面應用到了極致啊。。基本每初始化某個東西都會有其對應的PostProcessor,雖然看着略顯繁瑣,但是卻極大的增加了我們的擴展點
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { //將我們的BeanFactory強轉為BeanDefinitionRegistry BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>(); //循環我們傳入的BeanFactoryPostProcessor 如果其是BeanDefinitionRegistryPostProcessor //那么這兒執行其postProcessBeanDefinitionRegistry方法 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } }
上述代碼也是執行了傳入的Proccessor類型為BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
4.2 第一級BeanDefinitionRegistryPostProcessor執行(即實現了PriorityOrdered接口)
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 找到系統所有實現了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor接口實現類
// 這兒會找到我們剛剛的 ConfigurationClassPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //將剛找到的BeanDefinitionRegistryPostProcessor加入registryProcessors registryProcessors.addAll(currentRegistryProcessors); //執行剛找到的BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //清空 currentRegistryProcessors.clear();
這兒即找實現了BeanDefinitionRegistryPostProcessor,PriorityOrdered的類。而我們在第一節中最后提到的ConfigurationClassPostProcessor剛好是滿足的,我們可以在回顧一下
這兒我們進入invokeBeanDefinitionRegistryPostProcessors方法看下
private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
可以看到是迭代所有BeanDefinitionRegistryPostProcessor並執行其postProcessBeanDefinitionRegistry方法。而上面說到我們會拿到ConfigurationClassPostProcessor,所以這兒我們直接看ConfigurationClassPostProcessor的方法,由於該方法是spring進行配置解析的重中之重,所以篇幅較長
4.2.1 校驗並為本次解析設置id,防止重復加載
第一步則是設置了本次解析的id,防止重復解析
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { //得到registry的hash碼作為id int registryId = System.identityHashCode(registry); //校驗id 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); }
4.2.2 正式解析
這兒我們依舊一段一段的看
List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //找到該registry所有的candidateNames 也就是我們第一步結尾添加的那些 String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //isFullConfigurationClass 判斷是否是帶有@Configuration //isLiteConfigurationClass 判斷是否帶有@Component,@ComponentScan,@Import,@ImportResource,@Bean 5個注解中的任一個 // 具體可以查看 https://blog.csdn.net/u011624903/article/details/102564491 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 這兒由於我們的主啟動類中@SpringbootApplication帶@Configuration注解 所以主類滿足 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found if (configCandidates.isEmpty()) { return; }
// 排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
這兒會將BeanFactory中已經存在的BeanDefinitionName全部查出來並獲取其BeanDefinition,由於我們的啟動類@SpringbootApplication中已經帶有@Configuration 所以這里是滿足的(第一節中講組合注解的時候講過)
然后接下來會有查看是否有BeanNameGenerator和environment
SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); }
然后我們就看到了本文最核心的代碼了,也就是解析代碼。
我們看下這個解析流程
// 構建一個ConfigurationClassParser 也就是解析器 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); //拿到我們解析的配置類 這兒的話是主啟動類 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); //已經解析的ConfigurationClass集合 Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { //開始解析 parser.parse(candidates); //驗證 parser.validate(); //找到本次解析后發現的所有ConfigurationClass Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); //移除掉已經解析的 configClasses.removeAll(alreadyParsed); // 如果沒有 則創建一個新的ConfigurationClassBeanDefinitionReader if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } //將這些發現的找到本次解析后發現的所有ConfigurationClass再次解析掉 this.reader.loadBeanDefinitions(configClasses); //將其添加到已解析的集合中 alreadyParsed.addAll(configClasses); //清空candidates candidates.clear(); //如果registry中的BeanDefinition數量大於candidateNames 也就是一開始進入方法時的數量 //即找到的新的需要加入容器的bean了 if (registry.getBeanDefinitionCount() > candidateNames.length) { //拿到所有的已經存在的BeanDefinitionName String[] newCandidateNames = registry.getBeanDefinitionNames(); //初始進來的BeanDefinitionName Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); //創建已經解析的Class的名字的集合 Set<String> alreadyParsedClasses = new HashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { //將已經解析的添加到集合中 alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } //循環遍歷 所有的BeanDefinition 看看有沒有configuration被遺漏的 for (String candidateName : newCandidateNames) { //即不是初始化進來時的BeanDefinition if (!oldCandidateNames.contains(candidateName)) { //拿到這個BeanDefinition BeanDefinition bd = registry.getBeanDefinition(candidateName); //如果該BeanDefinition也是一個配置類並且沒有存在於alreadyParsed 即被遺漏了 //那么將其添加到candidates方法 然后再進行 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { //則再將其添加進去 循環進行解析 candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while (!candidates.isEmpty());
這段代碼較長,邏輯還是較為清晰,其實通過這段代碼我們就大概明白了springboot進行配置加載的流程了。即根據主啟動類進行配置解析,並且將所有遇到的ConfigurationClass全部返回,然后再進行二次解析,最后對所有的BeanDefinition進行校驗,如果發現其為ConfigurationClass但是卻沒有在已解析的集合中,那么久循環一下,再次進行解析。
篇幅有限,具體的解析流程放到下一篇, 解析完第一級BeanDefinitionRegistryPostProcessor后我們開始解析第二級
4.3 第二級BeanDefinitionRegistryPostProcessor(即實現了Ordered接口)
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) {
//過濾了第一級中存在的 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear();
可以發現其流程和第一級幾乎一致,只是增加了一個過濾掉了第一級,所以這兒不講,如果有自定義的BeanDefinitionRegistryPostProcessor可以測試一下。
4.4 第三級BeanDefinitionRegistryPostProcessor
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); }
處理流程也和前兩級幾乎一致,這兒也不講了
4.4 BeanFactoryPostProcessor的執行
即找到系統存在的BeanFactoryPostProcessor,同樣按照三級的形式根據優先級來執行。具體的邏輯也和上面詳細講的那個一級是一致的。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); //找到所有的BeanFactoryPostProcessor 並根據其級別進行歸類 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 執行優先級最高的 即實現了PriorityOrdered接口的 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 執行第二級的的 即實現了Ordered接口的 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 執行第三級的的 即啥都沒實現的 sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); //清除緩存 beanFactory.clearMetadataCache();
到此,refresh方法中的兩個重要方法第一個 invokeBeanFactoryPostProcessors,已經完成,而其中的ConfigurationClassPostProcessor(也就是BeanDefinitionRegistryPostProcessor的一種)負責了最為核心的容器類加載,也就是主要分析的類也分析完成。(詳細的類解析過程篇幅問題放在下章)
總結
本文主要分為了兩個部分,創建Spring應用上下文,和執行了其refresh方法中的invokeBeanFactoryPostProcessors方法。
創建應用上下文的同時也會創建一個DefaultListableBeanFactory,這個也是靜態代理的體現。而在執行ApplicationContext的構造函數時,會創建一個AnnotatedBeanDefinitionReader,而這個類中會有一個BeanDefinitionRegistry屬性,並將我們一些必須的BeanDefinition添加進去,例如最為核心的 ConfigurationClassPostProcessor也就是在這個時候被添加進去的。
執行invokeBeanFactoryPostProcessors方法則主要分為三個步驟
- 執行所有傳入的BeanFactoryPostProcessor(如果為BeanFactoryPostProcessor)的postProcessBeanDefinitionRegistry方法
- 找到BeanFactory中所有的BeanDefinitionRegistryPostProcessor類型的類並按照三級標准執行(實現了PriorityOrdered接口,實現了Ordered接口,啥都沒實現 );
- 找到BeanFactory中所有的BeanFactoryPostProcessor類型的類並按照三級標准執行(實現了PriorityOrdered接口,實現了Ordered接口,啥都沒實現 );
而其第二步則執行了核心的ConfigurationClassPostProcessor,並且是以最優先級執行,該processer會加載系統中所有需要加入容器的類,並且會解析所有的Configuration class