Fork me on GitHub

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的区别

 

posted @ 2020-06-13 15:41  猿起缘灭  阅读(1120)  评论(0编辑  收藏  举报