当前位置: 首页 > news >正文

Spring Ioc 容器启动流程

Spring容器的启动流程

本文基于 Spring 5.3.23

基于XML文件

public void test() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");User user = applicationContext.getBean("user", User.class);
}

我们进入 ClassPathXmlApplicationContext() 源码

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);
}

显示的是调用另外一个方法

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}
}

我们可以看到,这个方法就只运行了三行代码:我们逐个分析

super(parent) parent 为 null。我们进入源码看看到底做了什么

super(parent)源码分析

public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {super(parent);
}
public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {super(parent);
}
public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {super(parent);
}
public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();setParent(parent);
}

我们发现它一直向上调用父类的方法,一直到

public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();setParent(parent);
}

我们来看看这个 this()函数做了什么

this()源码分析

public AbstractApplicationContext() {this.resourcePatternResolver = getResourcePatternResolver();
}

大致就是 给 AbstractApplicationContext这个抽象类的 resourcePatternResolver属性赋值。

我们来看看 getResourcePatternResolver();做了什么

getResourcePatternResolver();源码分析

protected ResourcePatternResolver getResourcePatternResolver() {return new PathMatchingResourcePatternResolver(this);
}

大致就是 创建了一个 PathMatchingResourcePatternResolver类的实例对象并返回。

这里 提供了一个参数 this 让我们看看getResourcePatternResolver()函数所在的类是什么样子的。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext{}

继承了一个 AbstractApplicationContext类,实现了ConfigurableApplicationContext接口。很好,先到这里,放我们进去

PathMatchingResourcePatternResolver()源码,看看这个 this到底代表了什么。

PathMatchingResourcePatternResolver()源码分析

public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {Assert.notNull(resourceLoader, "ResourceLoader must not be null");this.resourceLoader = resourceLoader;
}

看到这我们应该明白了 this 就是代表一个 resourceLoader。毕竟 AbstractApplicationContext类继承了 DefaultResourceLoader类。到这里 this()就到头了,大概就是初始化了一个 资源加载器resourceLoader


public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();setParent(parent);
}

接下来我们来看看setParent(parent)做了什么

setParent(parent)源码分析

public void setParent(@Nullable ApplicationContext parent) {this.parent = parent; //赋值if (parent != null) {//获取 parent 对象的环境Environment parentEnvironment = parent.getEnvironment();//如果这个环境是 ConfigurableEnvironment 的实例if (parentEnvironment instanceof ConfigurableEnvironment) {//将 parentEnvironment 强制转换为 父环境,同时,将父环境的配置合并到当前环境getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);}}
}
//简而言之,这段代码的作用是设置当前对象的父应用程序上下文,并在父上下文存在且为可配置环境时,将其环境的配置合并到当前环境中。

emmm,我们一路传递上来的 parent 好像是 null 呀。那个这好像就没有发挥什么作用。

public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();setParent(parent);
}

这个代码就解析完了。就大概初始化了资源解析器。。


public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}
}

接下来分析 setConfigLocations(configLocations);做了什么

setConfigLocations(configLocations);源码分析

我们要先知道 String[] configLocations 这个数组里就一个String对象 applicationContext.xml

public void setConfigLocations(@Nullable String... locations) {if (locations != null) {//地址为不空(其实就是配置文件)Assert.noNullElements(locations, "Config locations must not be null");this.configLocations = new String[locations.length]; //根据文件的数量for (int i = 0; i < locations.length; i++) {// configLocation 也是一个 String 类型的数组this.configLocations[i] = resolvePath(locations[i]).trim();}}else {this.configLocations = null;}
}

我们来看看 configLocations[i]中具体存的什么东西

this.configLocations[i] = resolvePath(locations[i]).trim();

resolvePath()源码分析

protected String resolvePath(String path) {return getEnvironment().resolveRequiredPlaceholders(path);
}

我们看看 getEnvironment()做了什么

public ConfigurableEnvironment getEnvironment() {if (this.environment == null) {this.environment = createEnvironment();}return this.environment;}

创建了一个 ConfigurableEnvironment接口类型的对象。

protected ConfigurableEnvironment createEnvironment() {return new StandardEnvironment();
}

实际是 StandardEnvironment类型的对象。

然后用我们创建的对象去调用 resolveRequiredPlaceholders()函数,此时 path 仍旧是 applicationContext.xml

我们去resolveRequiredPlaceholders()源码看看

String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;

一个接口的方法,还是要去实现类看看。

在这里插入图片描述

我们去 第一个 AbstractEnvironment类中去看看

public abstract class AbstractEnvironment implements ConfigurableEnvironment {}

这不巧了吗,我们刚生成了一个 ConfigurableEnvironment接口类型的对象,

我们来看看 AbstractEnvironment类中 resolveRequiredPlaceholders()干了什么

public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {return this.propertyResolver.resolveRequiredPlaceholders(text);
}

继续深入。

public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {if (this.strictHelper == null) {this.strictHelper = createPlaceholderHelper(false);}return doResolvePlaceholders(text, this.strictHelper);
}

很好,已经看不懂了。。。。。。。。。。谁来九九我。

学个单词 Placeholder:占位符。

那么这个 doResolvePlaceholders()这个函数大致做了什么。我们可以大胆的猜一下。text就是我们传过来的配置文件的文件名。

那么这个函数大概就是 对我们的文件名 进行了 一些 操作,比如处理处理一下占位符啥啥的。

好了,我不会了。就先到这里

this.configLocations[i] = resolvePath(locations[i]).trim();

这行代码大概就是对我们的文件名做了点操作。我太菜了,只能看到这里。

感兴趣的 spring setConfigLocations方法分析_blueskygotohz的博客-CSDN博客文章走起


public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}
}

我们传递的 refresh为 true 也就是 一定会运行 refresh()函数。这也是 spring中最重要的一个函数。

refresh()源码分析

@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//先加个锁StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");//1// Prepare this context for refreshing.//准备此上下文以进行刷新prepareRefresh();//2// Tell the subclass to refresh the internal bean factory.//告诉子类刷新内部 Bean 工厂。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//3// Prepare the bean factory for use in this context.//准备 Bean 工厂以在此上下文中使用。prepareBeanFactory(beanFactory);//4try {// Allows post-processing of the bean factory in context subclasses.//允许在上下文子类中对 Bean 工厂进行后处理。postProcessBeanFactory(beanFactory);//5//不知道是个什么东西StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.//调用在上下文中注册为 Bean 的工厂处理器。invokeBeanFactoryPostProcessors(beanFactory); // 6// Register bean processors that intercept bean creation.//注册截获 Bean 创建的 Bean 处理器。registerBeanPostProcessors(beanFactory);//7beanPostProcess.end();// Initialize message source for this context.//初始化此上下文的消息源。initMessageSource();//8// Initialize event multicaster for this context//初始化此上下文的事件多播器。initApplicationEventMulticaster();//9// Initialize other special beans in specific context subclasses.//在特定上下文子类中初始化其他特殊 bean。onRefresh();// 可以提供子类重写这个方法,在容器刷新时,做些其它操作// Check for listener beans and register them.//检查侦听器 Bean 并注册它们。registerListeners();//10// Instantiate all remaining (non-lazy-init) singletons.//实例化所有剩余的(非惰性初始化)单例。finishBeanFactoryInitialization(beanFactory);//11// Last step: publish corresponding event.//最后一步:发布相应事件finishRefresh();}catch (BeansException ex) {...}finally {....}}
}

我滴妈,这么多。一点一点看吧。。注意注意 refresh()函数 是在 AbstractApplicationContext类中,其实就是 应用上下文容器

1、

StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

不知道干了点啥,不看了

2、 prepareRefresh();

做了一些简单的准备工作

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis(); //开始时间this.closed.set(false);//设置当前容器未关闭this.active.set(true);//设置当前容器已激活//打印容器刷新日志if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing " + this);}else {logger.debug("Refreshing " + getDisplayName());}}//初始化一下属性(该方法默认是空的,是提供给子类来实现的,//假设我们有些工作需要在初始化bean以前就要加载设置等,可以通过重写这个方法来完成)initPropertySources();//校验设置的属性是否合法 //同样是交给子类去实现getEnvironment().validateRequiredProperties();//初始化 早期应用监听器if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}//初始化一个集合属性,提供用来保存后面创建的事件,如果有事件发生会放入这个集合中//初始化早期应用事件this.earlyApplicationEvents = new LinkedHashSet<>();}

3、获取一个 beanFactory

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();
}

refreshBeanFactory(): 下面是子类的一个实现

protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) { //已经有工厂了destroyBeans();//破坏所有的 beancloseBeanFactory();//关闭这个工厂}try {DefaultListableBeanFactory beanFactory = createBeanFactory(); //创建一个工厂//设置bean工厂的序列化 id beanFactory.setSerializationId(getId());//自定义bean工厂customizeBeanFactory(beanFactory);//加载bean定义信息loadBeanDefinitions(beanFactory);this.beanFactory = beanFactory;}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}
}

getBeanFactory()

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {DefaultListableBeanFactory beanFactory = this.beanFactory;//这是我们刚才生成的if (beanFactory == null) {throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return beanFactory;//返回去
}
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

这行代码就是获取一个全新的 beanFactory

4、 prepareBeanFactory(beanFactory) : 大致就是做了一些预处理

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());//设置一个 bean 加载器//表达式语言解析器if (!shouldIgnoreSpel) {beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.//设置添加一个 ApplicationContextAwareProcessor 后置处理器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.ignoreDependencyInterface(ApplicationStartupAware.class);//注册可以解析的自动装配//假设想要使用@Autowired 注解将Spring提供的 BeanFactory 装配到自己创建的某个类的属性上,就要在此处设置beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);//设置添加一个ApplicationListenerDetector后置处理器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));//添加编译时支持AspectJif (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.//注册默认的环境 bean //且是单例模式if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {//注册了一个 Environment,该对象中存了一下我们默认的属性beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {//向beanFactory中注册了系统属性属性(一个Map集合)beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {//向beanFactory中注册环境变量等相关信息(一个Map集合)beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {//向beanFactory中注册 ApplicationStartup 对象。beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}
}

5、postProcessBeanFactory(beanFactory);

该方法默认是空的,为子类通过的,假设后续开发中,在 beanFactory 创建并且有准备完成后需要执行某些操作,可以提供子类重写这个方法来实现

以上可以看为beanFactory 的创建及预准备工作===========

6、 invokeBeanFactoryPostProcessors(beanFactory)

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {//执行beanFactory后置处理器中的方法,该方法中获取所有BeanFactoryPostProcessor,遍历判断//对不同的BeanFactoryPostProcessor进行排序,因为先后执行的顺序不同,//PriorityOrdered<BeanDefinitionRegistryPostProcessor>BeanFactoryPostProcessor//然后执行后置处理器中定义的初始化 beanFactory 后要执行的方法PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}

ok 卡! 在看下面的代码之前,了解点知识

什么是后处理(Post-processing)?

在Spring框架中,后处理(Post-processing)是指在应用程序上下文加载和初始化Bean之后,对这些Bean进行进一步的修改或处理的过程。后处理器是实现了相应接口的组件,它们可以在Spring容器生命周期的不同阶段进行自定义的操作。

在Spring中,有多个后处理器接口可供使用,包括:

  1. BeanPostProcessor:该接口定义了在Bean实例化和依赖注入完成之后,在初始化前后对Bean进行修改的方法。可以通过实现该接口来定制Bean的初始化逻辑,例如添加额外的初始化操作、修改属性值等。
  2. BeanFactoryPostProcessor:该接口允许在应用程序上下文创建所有单例Bean之前对Bean工厂进行修改。可以通过实现该接口来修改Bean工厂的配置,例如注册自定义编辑器、添加额外的Bean定义等。
  3. BeanDefinitionRegistryPostProcessor:该接口在Bean定义被加载到应用程序上下文之前,允许对Bean定义进行修改或添加新的Bean定义。可以通过实现该接口来动态注册Bean定义,修改Bean定义的属性等。

通过实现这些后处理器接口,开发人员可以对Spring容器中的Bean进行自定义操作,以满足特定的需求。后处理器在Spring的扩展机制中起到了重要的作用,使得开发者能够更加灵活地定制和扩展应用程序上下文的行为。

invokeBeanFactoryPostProcessors()

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {Set<String> processedBeans = new HashSet<>();/***1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,而				         *DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true*/if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;// regular: 常规  用来存储常规的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();// 用于存放BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// 2.首先处理入参中的beanFactoryPostProcessors// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通      BeanFactoryPostProcessor区分开for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {// 如果是BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;//直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法registryProcessor.postProcessBeanDefinitionRegistry(registry);//添加到registryProcessors(用于最后执行postProcessBeanFactory方法)registryProcessors.add(registryProcessor);}else {//加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)regularPostProcessors.add(postProcessor);}}// 用于保存本次要执行的BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.//找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanNameString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//遍历postProcessorNamesfor (String ppName : postProcessorNames) {// 校验是否实现了PriorityOrdered接口if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//获取ppName对应的bean实例, 添加到currentRegistryProcessors中,currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//将要被执行的加入processedBeans,避免后续重复执行processedBeans.add(ppName);}}// 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)sortPostProcessors(currentRegistryProcessors, beanFactory);//添加到registryProcessors(用于最后执行postProcessBeanFactory方法)registryProcessors.addAll(currentRegistryProcessors);//遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());//执行完毕后, 清空currentRegistryProcessorscurrentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.//找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,//可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// 校验是否实现了Ordered接口,并且还未执行过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);//遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.//最后, 调用所有剩下的BeanDefinitionRegistryPostProcessorsboolean reiterate = true;while (reiterate) {reiterate = false;//找出所有实现BeanDefinitionRegistryPostProcessor接口的类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);//如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,// 因此这边将reiterate赋值为true, 代表需要再循环查找一次reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);//遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.//调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,// 下面开始处理容器中的所有BeanFactoryPostProcessor//找出所有实现BeanFactoryPostProcessor接口的类String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);//用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanNameList<String> orderedPostProcessorNames = new ArrayList<>();//用于存放普通BeanFactoryPostProcessor的beanNameList<String> nonOrderedPostProcessorNames = new ArrayList<>();//遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开for (String ppName : postProcessorNames) {//跳过已经执行过的if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//添加实现了PriorityOrdered接口的BeanFactoryPostProcessorpriorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {//添加实现了Ordered接口的BeanFactoryPostProcessor的beanNameorderedPostProcessorNames.add(ppName);}else {//添加剩下的普通BeanFactoryPostProcessor的beanNamenonOrderedPostProcessorNames.add(ppName);}}//调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor//对priorityOrderedPostProcessors排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.//调用所有实现Ordered接口的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {//获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}//对orderedPostProcessors排序sortPostProcessors(orderedPostProcessors, beanFactory);//遍历orderedPostProcessors, 执行postProcessBeanFactory方法invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.//调用所有剩下的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {//获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}//遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...//清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType//因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...beanFactory.clearMetadataCache();}

在这里插入图片描述

7、registerBeanPostProcessors(beanFactory)

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {//根据类型获取 beanFactory 中所有的 BeanPostProcessor 名字String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;//添加了一个后置处理器,通过添加的这个后置处理器检查 前获取的这些后置处理器 //BeanPostProcessorChecker 是一个内部类,继承了BeanPostProcessor接口beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//创建两个集合用来存放不同的BeanPostProcessor,通过这两个集合对不同的BeanPostProcessor 进行排序List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// 首先对 priorityOrderedPostProcessors 中的进行排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//注册,也就是创建BeanPostProcessor设置到beanFactory中registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//对orderedPostProcessors集合中的后置处理器排序sortPostProcessors(orderedPostProcessors, beanFactory);//注册registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//注册nonOrderedPostProcessors集合中的后置处理器registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);//对internalPostProcessors集合中的后置处理器进行排序sortPostProcessors(internalPostProcessors, beanFactory);//注册internalPostProcessors集合中的后置处理器registerBeanPostProcessors(beanFactory, internalPostProcessors);//又添加了一个后置处理器ApplicationListenerDetector,//该后置处理器用来判断是否是某个监听器,如果是添加到容器中beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

在这里插入图片描述

8、 initMessageSource();

在 SpringMVC 中用来做国际化功能,消息解析,消息绑定,MessageSource中有getMessage()方法,一般用来取出国际化配置文件中的key的值,能按照区域信息去获取

protected void initMessageSource() {//获取beanFactoryConfigurableListableBeanFactory beanFactory = getBeanFactory();//判断beanFactory中是否有一个id为"messageSource" 的 beanif (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {//如果有通过id获取这个bean,赋值给 messageSource  属性this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");}}else {//如果没有创建一个MessageSource组件DelegatingMessageSource dms = new DelegatingMessageSource();//将这个组件注册到容器中(以后获取国际化配置文件的相关信息,可以通过@Autowired在Spring//容器中直接获取装配到自己的类的属性上,然后调用MessageSource的方法)dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isTraceEnabled()) {logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");}}
}

9、initApplicationEventMulticaster()

在这里插入图片描述

protected void initApplicationEventMulticaster() {//获取beanFactoryConfigurableListableBeanFactory beanFactory = getBeanFactory();//获取beanFactory中id为"applicationEventMulticaster"的事件派发器if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {//如果没有创建一个 SimpleApplicationEventMulticaster 事件派发器,this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);//注册到 Spring 容器中beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isTraceEnabled()) {logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");}}
}

10、registerListeners()

protected void registerListeners() {// Register statically specified listeners first.for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let post-processors apply to them!//在容器中拿到所有的监听器的名字String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//遍历,将每个监听器添加到事件派发器中for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// Publish early application events now that we finally have a multicaster...//获取早期设置的事件(派发之前的事件)Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;//如果有if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {将早期的事件派发出去getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

在这里插入图片描述

11、finishBeanFactoryInitialization(beanFactory)

涉及到bean的生命周期,看这篇文章(正在创作)

在这里插入图片描述

12、finishRefresh()

protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).clearResourceCaches();// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.if (!NativeDetector.inNativeImage()) {LiveBeansView.registerApplicationContext(this);}
}

在这里插入图片描述

emmmm 都是什么玩意,服了,不看了


总结

Spring中的Ioc 容器启动主要是在 AbstractApplicationContext # refresh() 方实现的。大致过程如下:

1、首先会执行一些容器刷新前的准备工作,如设置容器启动时间、一些状态标志位等

2、创建容器对象、其实就是实例化DefaultListableBeanFactory对象,这一步包含了bean定义信息的解析,解析后的属性都封装到DefaultListableBeanFactory的成员属性中了,如我们常见的beanDefinitionMapbeanDefinitionNames;

3、准备bean工厂,实际就是设置 beanFactory的一些属性

4、Spring提供了 postProcessorBeanFactory()方法给我们去扩展、例如我们可以注册一些特殊的BeanPostProcessor后置处理器等操作

5、执行BeanFactoryPostProcessor后置处理器的postProcessBeanFactory()增强方法,使三个不同的集合分别存放实现了PriorityOrdered接口、实现了Ordered接口、普通的BeanFactoryPostProcessor,经过排序后之执行BeanFactoryPostProcessor的回调postProcessorBeanFactory

6、第六步,注册BeanPostProcessor后置处理器,注意,这里还不会执行BeanPostProcessor对应的增强方法;同样的,使用三个不同的集合分别存放实现了PriorityOrdered接口、实现了Ordered接口、普通的BeanPostProcessor,依次调用beanFactory.addBeanPostProcessor(postProcessor)方法往bean工厂中添加BeanPostProcessor;

7、为上下文初始化MessageResource,即国际化处理

8、初始化事件多播器,即ApplicationEventMulticaster,为后面的事件发布-监听做准备

9、提供了一个模板方法onRefresh(),留给子类初始化其他的bean

10、注册Listener监听器

11、最关键的一步,这里会实例化所有剩下的非懒加载的单例Bean,Bean的生命周期也是从这里开始的。

12、完成上下文刷新工作,如清除一些缓存、发布容器刷新完成事件等。

http://www.lryc.cn/news/224341.html

相关文章:

  • 【714. 买卖股票的最佳时机含手续费】
  • JS前端实现身份证号码合法性校验(校验码校验)
  • 操作系统 day09(线程)
  • 单通道低压 H 桥电机驱动芯片AT9110H 兼容L9110 马达驱动芯片
  • 18. 深度学习 - 从零理解神经网络
  • Pycharm加载项目时异常,看不到自己的项目文件
  • 目标检测YOLO实战应用案例100讲-基于无人机的轻量化目标检测系统设计(续)
  • 大文件传输小知识 | UDP和TCP哪个传输速度快?
  • 【tgcalls】Instance接口的实例类的创建
  • 【java:牛客每日三十题总结-3】
  • 区块链多链数字钱包开发
  • hive-行转列
  • 【赠书第2期】嵌入式虚拟化技术与应用
  • 如何写一篇吊炸天的竞品分析
  • 校园安防监控系统升级改造方案:如何实现设备利旧上云与AI视频识别感知?
  • 刷题笔记day15-二叉树层序遍历
  • 前端 JS 经典:ES6 和 CommonJs 用法
  • MacOS升级后命令行出现xcrun: error: invalid active developer path报错信息
  • 【Qt】QPalette
  • 专门为Web应用程序提供安全保护的设备-WAF
  • Android Camera App启动流程解析
  • [工业自动化-8]:西门子S7-15xxx编程 - PLC主站 - CPU模块
  • QT事件循环和事件队列的理解
  • 【Android】画面卡顿优化列表流畅度一
  • SNP应邀参加2023中国企业数字化转型峰会暨赛意用户大会
  • 黑豹程序员-架构师学习路线图-百科:Knife4j API接口文档管理
  • PHP安全问题:远程溢出、DoS、safe_mode绕过漏洞
  • 2023云计算发展
  • javaSE学习笔记(六)泛型,异常
  • C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发006:基于redis查找玩家姓名+游戏业务实现总结