「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
1.前言
本文主要讲Spring IOC容器初始化过程中的onRefresh()方法 和 registerListeners() 方法,如想看之前的内容可查看 Spring IOC容器初始化原理分析 (第四节)
这两个方法都是在Spring IOC 容器初始化过程中 refresh()中调用的,其中 onRefresh()方法官方的定义是 初始化上下文其它特殊的bean , registerListeners() 方法,则见名知意就是检查并注册listener。
2.refresh()源码
如果需要复制代码,可前往Spring IOC容器初始化原理分析 (第一节)
- onfresh() 方法讲解
首先点进源码看看,默认是一个空方法。
接着看看官方的说法,上面的注释说了它是一个模板方法,我们可以重写该方法,以添加特定于上下文的刷新工作。可以用来初始化上下文其他特殊bean,在单例实例化前调用。
这里官方没有实现,我们可以查看一下扩展包中的实现,这里主要是了解一下这个方法的作用。
如图我们以第一个org.springframework.web.context.support.AbstractRefreshableWebApplicationContext#onRefresh为例,点进去看看,源码如下:
这个方法主要是初始化主题的。我们接着点进去看看,它调用的是:org.springframework.ui.context.support.UiApplicationContextUtils#initThemeSource
- 在这个方法中,他首先判断容器中是否包含一个 名为 themeSource 的bean.
- 如果有的话,则从容器中取到这个bean,判断一下容器的parent 是否属于 ThemeSource 且 themeSource 是否属于 HierarchicalThemeSource ,如果是 则把 themeSource 转成 HierarchicalThemeSource 对象,设置一下它的 ParentThemeSource。返回themeSource
- 如果没有的话,则他会帮我们定义一个 HierarchicalThemeSource 类型的 themeSource 变量置为null,判断当前 context 的parent 是否属于 ThemeSource 。 如果是则把 themeSource 实例化成DelegatingThemeSource 对象,并设置下它的 ParentThemeSource,否则把它实例化成 ResourceBundleThemeSource 对象。最终返回themeSource。
总结:可以看到在这个方法中,它就给我们定义了一个特殊bean (themeSource)。所以这个方法的主要作用就是添加一些特殊bean。
4.registerListeners() 方法
老样子,我们接着进源码,这里为了大家更直观的看,我就直接把源码复制过来,直接在上面讲
1 | scss复制代码protected void registerListeners() { |
这里我把重点列出来细讲一下:
- getApplicationListeners() : 返回容器中静态的 ApplicationListener 集合,源码如下:
- getApplicationEventMulticaster() 拿到前面注册的 ApplicationEventMulticaster,如果没有就抛异常。 这里它的注册过程在 Spring IOC容器初始化原理分析 (第四节) 中 写的比较详细,这里就不讲了。
- addApplicationListener() 这就是添加一个 ApplicationListener
这里面它们面共同组成了 观察者设计模式, 当容器中的某些内部状态发生改变时,ApplicationEventMulticaster 会通知 ApplicationListener。
- ApplicationEventMulticaster 即(Subject 角色)
- AbstractApplicationEventMulticaster 或它的子类 SimpleApplicationEventMulticaster
(Concrete Subject 角色) 实现了 ApplicationEventMulticaster 中的增加,移除,通知观察者的类 - ApplicationListener (Observer 角色) 提供了一个被调用的方法
- ApplicationListener的子类则是(Concrete Observer 角色)
不懂可以看上面的文章。
- 第二个for循环和第一个基本一样,不同的是一个是保存 ApplicationListener对象引用,一个是保存对象名这里我就不细讲了。
- this.earlyApplicationEvents :这里保存的容器早期发布的一些事件
- multicastEvent() :观察者模式中 Subject 角色 通知所有观察者的方法,当 earlyApplicationEvents 不为空时,ApplicationEventMulticaster就调用 multicastEvent(event),通知所有的观察者。源码如下:
1 | typescript复制代码@Override |
5.今天的分析就到这里了,后面没讲完的,我会继续在后续内容中更新。
本文转载自: 掘金