likes
comments
collection
share

Spring的启动流程探索

作者站长头像
站长
· 阅读数 33

run方法

我们都知道springboot工程是通过run方法启动的,如图:

Banner printedBanner = this.printBanner(environment);就是我们熟悉的springboot工程启动的时候在控制台打印的log,我们也可以通过配置改变log的打印。

一,context = this.createApplicationContext()

Spring的启动流程探索 我们先介绍context = this.createApplicationContext();方法,这个方法顾名思义是创建应用上下文的,应用上下文我们都知道是用来扫描Bean的,并且种类很多。那我们spring使用了应用上下文那些去获取Bean吗,打断点进入这个方法

Spring的启动流程探索 可以看到在这里new AnnotatedBeanDefinitionReader(this);new了一个用于读取带有注解的Bean对应的BeanDefinition,还new了一个new ClassPathBeanDefinitionScanner(this);用于从路径读取Bean的BeanDefinition。

在new AnnotatedBeanDefinitionReader的时候会去调用它的构造方法,在它的构造方法里面会去将它的AnnotatedBeanDefinitionReader的BeanDefinition加入到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap,这两个就是后面创建Bean必须的东西,所有Bean的注册底层都是使用的BeanDefinition。如图:

Spring的启动流程探索 添加到DefaultListableBeanFactory这个类的beanDefinitionNamesbeanDefinitionMapSpring的启动流程探索

Spring的启动流程探索

总的来说具体来说,createApplicationContext()方法会根据指定的配置文件(通常是XML文件)或Java配置类来创建和初始化ApplicationContext。配置文件中包含了应用程序中各种bean的定义和配置信息,Spring会根据这些信息创建出对应的bean实例,并将它们注入到相应的对象中,从而完成整个应用程序的初始化。

二,this.prepareContext()

Spring的启动流程探索 1context.setEnvironment(environment);这一步不用多说,就是将环境变量set到context中,设置上下文的环境。

2this.postProcessApplicationContext(context);这步操作主要是对ApplicationContext进行后置处理。那么做了哪些后置处理呢?我们点进去看下:

Spring的启动流程探索 主要做了3部分:1.设置ApplicationContext的beanNameGenerator。2.设置ApplicationContext的ResourceLoader和ClassLoader。3.设置ApplicationContext类型转换service

3this.applyInitializers(context); 这个方法就是获取之前获取到的所有initializer类型的类,并进行初始化。

4listeners.contextPrepared(context);这个方法是通知监听器 context 准备完成;

5if (this.logStartupInfo) { this.logStartupInfo(context.getParent() == null); this.logStartupProfileInfo(context); }这个代码就是打印日志,这里不做过多描述。

6ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();这个方法就是获取DefaultListableBeanFactory的实例。

7beanFactory.registerSingleton(“springApplicationArguments”, applicationArguments);这步操作是注册了一个单例,单例名为“springApplicationArguments”,值为applicationArguments。

8if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}这步是判断printedBanner是否为空,如果不为空,就注册一个名为springBootBanner,值为printedBanner的单例

9if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}这个方法主要是配置bean如果重名,是否允许后一个bean覆盖前一个bean,默认是false,此时如果有同名的bean,注册到容器中,那么就会报异常。

10Set<Object> sources = this.getAllSources();获取sources列表,这里可以获取到启动类的class

Spring的启动流程探索 11this.load(context, sources.toArray(new Object[0]));这个方法就是加载启动类,将启动类注入到容器里面。

Spring的启动流程探索 可以看到beanDefinitionNamesbeanDefinitionMap里面已经有6个了。都是主配置类。

Spring的启动流程探索 12listeners.contextLoaded(context);这个方法我们点进去看下:

Spring的启动流程探索

Spring的启动流程探索 这里就是将在SpringApplciationInitialize()方法中注册的listener中属于ApplicationContextAware类型的bean都执行方法setApplicationContext,同时将这些Listener都加入到ApplicationContext中,并发布事件ApplicationPreparedEvent

三,this.refreshContext(context)

这个就是刷新容器的方法 Spring的启动流程探索 1.this.prepareRefresh(),进入这个方法。

Spring的启动流程探索 this.startupDate = System.currentTimeMillis();设置容器启动的时间

this.closed.set(false);容器的关闭标志位

this.active.set(true);将容器状态设置为有效,

this.initPropertySources();留给子类覆盖,初始化属性资源

this.getEnvironment().validateRequiredProperties();创建并获取环境对象,验证需要的属性文件是否都已经放入环境中。

最后去判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到集合中。

三,ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory()

这个用于获取设置容器序列化id和BeanFactory

Spring的启动流程探索 1.this.refreshBeanFactory();,点进去看 Spring的启动流程探索 首先使用了CAS去判断容器是否已经启动,没有启动就给beanFactory设置一个序列化id。

Spring的启动流程探索 设置的序列化id就是你的服务名称。

2.this.getBeanFactory();,点进去看,调用了getBeanFactory方法获取了beanFactory,而beanFactory是在这个通用上下文构造方法里面就创建了的DefaultListableBeanFactory

Spring的启动流程探索

四,this.prepareBeanFactory(beanFactory)

点进去看 Spring的启动流程探索 这个方法就是给工厂设置必须的工具,比如el表达式解析器,资源解析器,后置处理器等。

五,this.postProcessBeanFactory(beanFactory)

这个是留给子类的模板方法,允许子类对工厂执行一些处理,给Bean设置属性,单例Bean修改为多例,或者移除BeanDefinition从而避免某个Bean在spring容器中的创建。例如:

Spring的启动流程探索 又或者用它的子类接口BeanDefinitionRegistryPostProcessor,如图

Spring的启动流程探索 最后别忘记把这两个配置类注入到容器当中

Spring的启动流程探索

六,this.invokeBeanFactoryPostProcessors(beanFactory)

这个就是去调用Bean工厂主处理器,

Spring的启动流程探索

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 将已经执行过的BeanFactoryPostProcessor存储在processedBeans,防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 此处条件成立,BeanFactory类型为DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用来存放BeanFactoryPostProcessor对象
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 用来存放BeanDefinitionRegistryPostProcessor对象
            // 方便统一执行实现了BeanDefinitionRegistryPostProcessor接口父类的方法
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 处理外部定义的BeanFactoryPostProcessor,将BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果为BeanDefinitionRegistryPostProcessor类型
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    // 强转成BeanDefinitionRegistryPostProcessor
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 如果是BeanDefinitionRegistryPostProcessor类型,直接执行postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    // 如果不是BeanDefinitionRegistryPostProcessor类型
                    // 则将外部集合中的BeanFactoryPostProcessor存放到regularPostProcessors用于后续一起执行
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            // 此处的currentRegistryProcessors存放当前需要执行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // TODO 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor。
            // 获取所有实现了BeanDefinitionRegistryPostProcessor接口的类名
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断当前类是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 将BeanDefinitionRegistryPostProcessor存入currentRegistryProcessors
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 提前存放到processedBeans,避免重复执行,但是此处还未执行
                    processedBeans.add(ppName);
                }
            }
            // 对currentRegistryProcessors接口中的BeanDefinitionRegistryPostProcessor进行排序,方便后续执行
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors集合,用于后续执行父接口的postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历集合,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕后,将currentRegistryProcessors清空
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // TODO 接下来,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
            // 这里为什么要再次获取BeanDefinitionRegistryPostProcessor
            // 是因为有可能在上面方法执行过程中添加了BeanDefinitionRegistryPostProcessor,所以这里再次获取
            // 而下面处理BeanFactoryPostProcessor的时候又不需要重复获取了是为什么呢?
            // 因为添加BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor
            // 中添加,在BeanFactoryPostProcessor是无法添加的,具体看方法参数就懂了
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断当前bean没有被执行过,并且实现了Ordered接口
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // getBean() 如果BeanFactory中没有该Bean则会去创建该Bean
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            // 以下操作和上面是一样的,排序-->添加到registryProcessors-->执行-->清空currentRegistryProcessors
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // TODO 最后处理没有实现Ordered与PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 再次获取BeanDefinitionRegistryPostProcessor
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        // 将本次要执行的BeanDefinitionRegistryPostProcessor存放到currentRegistryProcessors
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 提前存放到processedBeans,避免重复执行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 此处的排序已经没有意义了
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 将本次执行的BeanDefinitionRegistryPostProcessor添加到registryProcessors
                registryProcessors.addAll(currentRegistryProcessors);
                // 执行
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 清空
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // TODO 现在,调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调。
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            // BeanFactory如果不归属于BeanDefinitionRegistry类型,则直接执行beanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放实现了priorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了ordered接口的BeanFactoryPostProcessor名称
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放无排序的BeanFactoryPostProcessor名称
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            // 如果已经执行过了,则不做处理
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 如果实现了PriorityOrdered
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 如果实现了Ordered
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            // 无排序
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // TODO 首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // TODO 接下来,调用实现 Ordered 的 BeanFactoryPostProcessors。
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // TODO 最后,调用所有其他 BeanFactoryPostProcessor。
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 清空缓存
        beanFactory.clearMetadataCache();
    }

总的来说回去执行实现了BeanFactoryPostProcessor接口的类重写的方法,直接说最重要的一个子类-ConfigurationClassPostProcessor 来看看详解:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
 
        //获取所有BeanDefinition的名称
		String[] candidateNames = registry.getBeanDefinitionNames();
 
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
 
            //如果BeanDefinition 中的configurationClass 属性为full 或者lite ,则意味着已经处理过了,直接跳过
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
 
            //如果符合配置类候选条件(@Configuration修饰),加入configCandidates集合,后面根据优先级实例化配置bean
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}
 
        //如果没有配置类(@Configuration)则返回,这里找到了一个启动类,所以不用返回。
		if (configCandidates.isEmpty()) {
			return;
		}
 
        // 根据定义的Order排序
		Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
			@Override
			public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
				int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
				int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
				return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
			}
		});
 
        //如果BeanFactory中没设置componentScanBeanNameGenerator,则使用该componentScanBeanNameGenerator
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}
 
        // 实例化ConfigurationClassParser 为了解析每个@ configuration类
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
 
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
		do {
 
            //借助ConfigurationClassParser完成配置类解析,加载所有的配置类(@Configuration)到资源(Resource)中
			parser.parse(candidates);
 
            //配置类不能用final,因为要用cglib生成代理对象
			parser.validate();
 
			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);
 
			// 如果reader为null,则实例化ConfigurationClassBeanDefinitionReader
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
 
            //用ConfigurationClassBeanDefinitionReader解析资源Resource得到BeanDefiniton,然后注册到IOC容器中
			this.reader.loadBeanDefinitions(configClasses);
 
            //加入到alreadyParsed中,用于去重
			alreadyParsed.addAll(configClasses);
 
            //将candidates进行清空
			candidates.clear();
 
            //如果registry中注册的bean的数量 大于 之前获得的数量,则意味着在解析过程中又新加入了很多,那么就需要对其进行解析
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<String>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					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());
 
		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null) {
			if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
                // 如果SingletonBeanRegistry 不包含org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry
            // 则注册一个,bean 为 ImportRegistry. 一般都会进行注册的
				sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
			}
		}
 
        //清除缓存
		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

Spring的启动流程探索 点进去看一下。

Spring的启动流程探索 再点进去。

Spring的启动流程探索 在这里会拿到主启动类,然后再去扫描主启动类下面的Bean。

从这里进去。

Spring的启动流程探索

这就很清晰了,去获取项目中所有使用了@Component注解Bean。 Spring的启动流程探索 当然,这个类ConfigurationClassParser里面不止扫描使用了@Component注解的Bean。还有@Bean注解等等,如图

Spring的启动流程探索 光是知道在哪里把使用了这些注解的Bean解析出来还不够,需要知道怎么解析出来的,就像我们学习Spring的时候那样,是通过应用上下文扫描出来的,如图

Spring的启动流程探索 点进this.componentScanParser.parse这个方法

Spring的启动流程探索 可以看到new ClassPathBeanDefinitionScanner,在这里new了一个应用上下文扫描,这就是原理。 而且和我们介绍context = this.createApplicationContext()方法,里面构造函数创建的两个应用上下文中的一个是一样的。

至此项目中所有的Bean都被invokeBeanFactoryPostProcessors这个方法(ConfigurationClassPostProcessor最关键)解析出来。

Spring的启动流程探索 并且通过this.reader.loadBeanDefinitions(configClasses);这个方法放到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap,如图

Spring的启动流程探索 点进去,再点进这个方法,

Spring的启动流程探索 再点进这个方法,可以看到现在将我beanNamegetgiao的Bean注册到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap里面。 Spring的启动流程探索 如图: Spring的启动流程探索

七,this.finishBeanFactoryInitialization(beanFactory)

这个方法是将DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap初始化的,包括Spring三级缓存啊,这个下次再讲了。

转载自:https://juejin.cn/post/7267800436261748777
评论
请登录