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);//4
try {
// 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);//7
beanPostProcess.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();//破坏所有的 bean
closeBeanFactory();//关闭这个工厂
}
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));
//添加编译时支持AspectJ
if (!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中,有多个后处理器接口可供使用,包括:
- BeanPostProcessor:该接口定义了在Bean实例化和依赖注入完成之后,在初始化前后对Bean进行修改的方法。可以通过实现该接口来定制Bean的初始化逻辑,例如添加额外的初始化操作、修改属性值等。
- BeanFactoryPostProcessor:该接口允许在应用程序上下文创建所有单例Bean之前对Bean工厂进行修改。可以通过实现该接口来修改Bean工厂的配置,例如注册自定义编辑器、添加额外的Bean定义等。
- 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: 常规 用来存储常规的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 用于存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 2.首先处理入参中的beanFactoryPostProcessors
// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通 BeanFactoryPostProcessor区分开
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 如果是BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
}
else {
//加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
regularPostProcessors.add(postProcessor);
}
}
// 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历postProcessorNames
for (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());
//执行完毕后, 清空currentRegistryProcessors
currentRegistryProcessors.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.
//最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
boolean 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接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
//用于存放普通BeanFactoryPostProcessor的beanName
List<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接口的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
}
else {
//添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
//调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
//对priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//调用所有实现Ordered接口的BeanFactoryPostProcessor
List<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.
//调用所有剩下的BeanFactoryPostProcessor
List<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() {
//获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断beanFactory中是否有一个id为"messageSource" 的 bean
if (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() {
//获取beanFactory
ConfigurableListableBeanFactory 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
的成员属性中了,如我们常见的beanDefinitionMap
、beanDefinitionNames
;
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、完成上下文刷新工作,如清除一些缓存、发布容器刷新完成事件等。