概述
在学习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, ListbeanFactoryPostProcessors) { Set 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); ListorderedPostProcessors = 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 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) { ListconfigCandidates = 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 candidates = new LinkedHashSet(configCandidates); HashSet alreadyParsed = new HashSet(configCandidates.size()); do {
//这里就是解析每个bean parser.parse(candidates); parser.validate(); SetconfigClasses = 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 oldCandidateNames = new HashSet(Arrays.asList(candidateNames)); Set 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); } ListbeanNames = 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); } } }
这个方法,真是出奇的长,写的非常神奇,我还从没有写过这么多的循环嵌套,这个方法总的来说其实就是调用beanFactory.getBean()方法进行实例化bean,细节我是真没看头大
总结:这个方法非常重要,尤其是getBean方法,这个方法下一篇文章会分析
最后
一开始的打算是把每个方法仔细分析一遍,在分析的过程中发现确实没有多大必要,里面的逻辑写的太多,把核心的看一下就可以了,其实这个refresh()方法我写的比较简单,其实里面的逻辑还是挺多的。下一篇文章介绍getBean()方法
参考文章
SpringBoot源码分析之Spring容器的refresh过程
Spring源码-refresh方法
BeanFactory和FactoryBean的区别