springboot源碼分析(六)-refresh方法分析


概述

  在學習springboot時候,會牽涉到很多的知識,而refresh方法可以說其中的核心方法,為什么這么說,因為整個spring的核心aop和ioc都和這個方法有關,既然這個方法那么重要,那我們就分析一下這個方法到底干了什么。

refresh()調用的核心方法預覽

看了上面這個圖是不是都暈了,其實不用暈,這里面很多的方法只是在做一些准備的工作和監聽的工作,真正核心的就兩三個方法,那我就把核心的方法先列出來,

  • invokeBeanFactoryPostProcessors(beanFactory),核心方法,將程序中的所有bean放入到beanDefinitionMap中,注意這一步並沒有實例化bean,而是獲得bean的beanDefinition
  • finishBeanFactoryInitialization(beanFactory),核心方法,將上面放入到beanDefinitionMap中的非懶加載的bean都實例化,這兩個方法可以說是讓ioc起作用的核心方法

其實核心的方法我覺得就這兩個,剩下的都是一些准備性的工作,ok,下面我們就逐個分析一下每個方法,不重要的方法我就簡單說一下,我覺得沒必要每個方法都全部吃透,搞明白核心方法就可以了,spring代碼那么多,又不是自己要去寫一個spring,沒必要全部吃透。

prepareRefresh()

  這個方法,從名字就可以看出來,就是一個為了執行refresh()方法做准備的方法,下面我們看一下代碼

protected void prepareRefresh() {
     //設置開始時間
this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (this.logger.isDebugEnabled()) { if (this.logger.isTraceEnabled()) { this.logger.trace("Refreshing " + this); } else { this.logger.debug("Refreshing " + this.getDisplayName()); } }       this.initPropertySources();
     //校驗一些關鍵的環境信息是否存在
this.getEnvironment().validateRequiredProperties(); if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners); } else { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } this.earlyApplicationEvents = new LinkedHashSet(); }

總結:這個方法總的來說就是設置了一下啟動的時間,校驗了一下環境參數。

obtainFreshBeanFactory()

  這個方法從名稱也可以看出來獲取beanFactory的,至於beanFactory是什么,相信大家也應該清楚,整個spring的核心接口,用於生產bean,為他的實現類DefaultListableBeanFactory,ApplicationContext等提供了最基本的規范,下面看一下代碼

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }

第一個方法refreshBeanFactory,這個方法就是未beanFactory設置了一個序列化id,我們主要看一下第二個,這里使用了模板模式,真是實現這個getBeanFactory()的是GenericApplicationContext(),我們看一下這個類的構造方法

    public GenericApplicationContext() {
        this.customClassLoader = false;
        this.refreshed = new AtomicBoolean();
     //這里new了一個beanFactory
this.beanFactory = new DefaultListableBeanFactory(); }

我們看一下this.getBeanFactory();方法代碼

 public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }

總結:obtainFreshBeanFactory()方法就是為了返回new DefaultListableBeanFactory();

 

this.prepareBeanFactory(beanFactory);

  同樣,從名字就可以看出來是為beanFactory做一些准備工作,因為上一步已經獲取到beanFactory

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
     //這里設置了一個beanPostProcessor,這個接口的作用后面再說,這個接口和AOP有關 beanFactory.addBeanPostProcessor(
new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); if (beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } if (!beanFactory.containsLocalBean("environment")) { beanFactory.registerSingleton("environment", this.getEnvironment()); } if (!beanFactory.containsLocalBean("systemProperties")) { beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean("systemEnvironment")) { beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment()); } }

總結:這個里面代碼一大坨,基本就是向beanFactory中設置了一個屬性,為了后面使用。

postProcessBeanFactory(beanFactory);

  這個方法在這里並沒有實現,而是交給了子類實現,這里就不分析了

invokeBeanFactoryPostProcessors(beanFactory);

  這個就是核心方法了,看一下代碼

 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }

進入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());

  這個代碼很長,但是大家不要怕,里面很多個循環只是在做重復的事情

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        ArrayList regularPostProcessors;
        ArrayList registryProcessors;
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
     //先判斷beanFactory是不是實現了BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory; regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); Iterator var6 = beanFactoryPostProcessors.iterator(); while(var6.hasNext()) { BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
          //判斷postProcessor是不是BeanDefinitionRegistryPostProcessor,這個接口繼承了BeanFactoryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
            //執行方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); }
else { regularPostProcessors.add(postProcessor); } } currentRegistryProcessors = new ArrayList();
       //獲取beanFactory中實現了BeanDefinitionRegistryPostProcessor接口的bean postProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); String[] var16 = postProcessorNames; var9 = postProcessorNames.length; int var10; String ppName; for(var10 = 0; var10 < var9; ++var10) { ppName = var16[var10]; if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } }        //對postProcessor排序 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors);
       //<1.1>,執行postProcessor的postProcessBeanDefinitionRegistry()方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
       //執行完了之后,清空當前的后置處理器列表 currentRegistryProcessors.clear();
       //<1.2>這一步和上一步的過程一樣,但是這里獲取到的這個處理器非常重要,是ConfigurationClassPostProcessor,這個類會處理所有的bean,並把其beanDefinition放入beanDefinitionMap中 postProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); var16 = postProcessorNames; var9 = postProcessorNames.length; for(var10 = 0; var10 < var9; ++var10) { ppName = var16[var10]; 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(); boolean reiterate = true; while(reiterate) { reiterate = false;

          //這里的過程依然是一樣的,把所有的postProcessor都執行一遍 postProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); String[] var19 = postProcessorNames; var10 = postProcessorNames.length; for(int var26 = 0; var26 < var10; ++var26) { String ppName = var19[var26]; 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(); } invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } else { invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); currentRegistryProcessors = new ArrayList(); postProcessorNames = postProcessorNames; int var20 = postProcessorNames.length; String ppName; for(var9 = 0; var9 < var20; ++var9) { ppName = postProcessorNames[var9]; if (!processedBeans.contains(ppName)) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { registryProcessors.add(ppName); } else { currentRegistryProcessors.add(ppName); } } } sortPostProcessors(regularPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size()); Iterator var21 = registryProcessors.iterator(); while(var21.hasNext()) { String postProcessorName = (String)var21.next(); orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size()); Iterator var24 = currentRegistryProcessors.iterator(); while(var24.hasNext()) { ppName = (String)var24.next(); nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); beanFactory.clearMetadataCache(); }

 這個方法中寫了很多的循環,每個循環干了什么事情呢?

  • 找出beanFactory中所有的實現了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的bean
  • 對找出來的postProcessor進行排序
  • 執行postProcessor中的postProcessBeanDefinitionRegistry()方法和postProcessBeanFactory()方法

那估計大家都有疑問了,為什么要寫那么多循環,一個循環不就ok了,我自己覺得寫一個中間那個while(reiterate)就可以了,沒搞明白spring為什么要在這個while之前還要搞兩個循環

<1.1>處代碼

    private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
        Iterator var2 = postProcessors.iterator();

        while(var2.hasNext()) {
            BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
       //就是調用每個postProcessor中的方法 postProcessor.postProcessBeanDefinitionRegistry(registry); } }

<1.2>處代碼,ConfigurationClassPostProcessor,我們看一下這個類的回調函數

 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);
        } else if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
        } else {
      
this.registriesPostProcessed.add(registryId);
       //執行這里的代碼
this.processConfigBeanDefinitions(registry); } }

進入this.processConfigBeanDefinitions(registry);

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList();
        String[] candidateNames = registry.getBeanDefinitionNames();
        String[] var4 = candidateNames;
        int var5 = candidateNames.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String beanName = var4[var6];
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
            } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
            }
        }

        if (!configCandidates.isEmpty()) {
            configCandidates.sort((bd1, bd2) -> {
                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                return Integer.compare(i1, i2);
            });
            SingletonBeanRegistry sbr = null;
            if (registry instanceof SingletonBeanRegistry) {
                sbr = (SingletonBeanRegistry)registry;
                if (!this.localBeanNameGeneratorSet) {
                    BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
                    if (generator != null) {
                        this.componentScanBeanNameGenerator = generator;
                        this.importBeanNameGenerator = generator;
                    }
                }
            }

            if (this.environment == null) {
                this.environment = new StandardEnvironment();
            }

            ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
            Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
            HashSet alreadyParsed = new HashSet(configCandidates.size());

            do {
          //這里就是解析每個bean parser.parse(candidates); parser.validate(); Set
<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet(); Iterator var12 = alreadyParsed.iterator(); while(var12.hasNext()) { ConfigurationClass configurationClass = (ConfigurationClass)var12.next(); alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } String[] var23 = newCandidateNames; int var24 = newCandidateNames.length; for(int var14 = 0; var14 < var24; ++var14) { String candidateName = var23[var14]; if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while(!candidates.isEmpty()); if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache(); } } }

有興趣的可以進入parse看一下,這個就是我們每次寫程序寫了很多的@Service,@Component,@Controller,都是這里解析的

總結:這個方法我只分析了invokeBeanFactoryPostProcessors,沒有詳細分析剩下的一大堆,如果有興趣可以看看:【Spring】簡述@Configuration配置類注冊BeanDefinition到Spring容器的過程

finishBeanFactoryInitialization(beanFactory)

  由於中間幾個方法都不重要,就不分析了,直接分析這個方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
     //這一步就是將所有的非懶加載的bean初始化的步驟 beanFactory.preInstantiateSingletons(); }
進入beanFactory.preInstantiateSingletons();
public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + this);
        }

        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            String beanName;
            Object bean;
            do {
                while(true) {
                    RootBeanDefinition bd;
                    do {
                        do {
                            do {
                                if (!var2.hasNext()) {
                                    var2 = beanNames.iterator();

                                    while(var2.hasNext()) {
                                        beanName = (String)var2.next();
                                        Object singletonInstance = this.getSingleton(beanName);
                                        if (singletonInstance instanceof SmartInitializingSingleton) {
                                            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                            if (System.getSecurityManager() != null) {
                                                AccessController.doPrivileged(() -> {
                                                    smartSingleton.afterSingletonsInstantiated();
                                                    return null;
                                                }, this.getAccessControlContext());
                                            } else {
                                                smartSingleton.afterSingletonsInstantiated();
                                            }
                                        }
                                    }

                                    return;
                                }

                                beanName = (String)var2.next();
                                bd = this.getMergedLocalBeanDefinition(beanName);
                            } while(bd.isAbstract());
                        } while(!bd.isSingleton());
                    } while(bd.isLazyInit());

                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }

                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

            FactoryBean<?> factory = (FactoryBean)bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                SmartFactoryBean var10000 = (SmartFactoryBean)factory;
                ((SmartFactoryBean)factory).getClass();
                isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
            } else {
                isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
            }

            if (isEagerInit) {
                this.getBean(beanName);
            }
        }
    }
View Code

這個方法,真是出奇的長,寫的非常神奇,我還從沒有寫過這么多的循環嵌套,這個方法總的來說其實就是調用beanFactory.getBean()方法進行實例化bean,細節我是真沒看頭大

總結:這個方法非常重要,尤其是getBean方法,這個方法下一篇文章會分析

 


最后

  一開始的打算是把每個方法仔細分析一遍,在分析的過程中發現確實沒有多大必要,里面的邏輯寫的太多,把核心的看一下就可以了,其實這個refresh()方法我寫的比較簡單,其實里面的邏輯還是挺多的。下一篇文章介紹getBean()方法

 

參考文章

SpringBoot源碼分析之Spring容器的refresh過程

Spring源碼-refresh方法

BeanFactory和FactoryBean的區別

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM