SpringMVC中的ContextLoaderListener设计困惑
SpringMVC中的ContextLoaderListener设计困惑
hanzhankang 发表于2年前
SpringMVC中的ContextLoaderListener设计困惑
  • 发表于 2年前
  • 阅读 192
  • 收藏 6
  • 点赞 0
  • 评论 4

腾讯云 技术升级10大核心产品年终让利>>>   

最近在学习Spring MVC原理相关部分,就按顺序从ContextLoaderListener来看,但是我在阅读此类的设计中,遇到了些困惑的地方,现纪录如下,希望能遇到高手能帮我答疑解惑:

ContextLoaderListener 类的定义:

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
	private ContextLoader contextLoader;
	public ContextLoaderListener() {
	}

	public ContextLoaderListener(WebApplicationContext context) {
		super(context);
	}

	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	@Deprecated
	protected ContextLoader createContextLoader() {
		return null;
	}

	@Deprecated
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}

	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event.getServletContext());
		}
		ContextCleanupListener.cleanupAttributes(event.getServletContext());
	}

}



困惑一:

ContextLoaderListener类已经继承了ContextLoader,为何又声明了一个私有的ContextLoader类的 对象属性contextLoader?而这个 contextLoader 在上下文的 意义愚以为仅仅是显示的说明 contextLoader 其实就是"this"。(我仿照ContextLoaderListener写了个去掉contextLoader属性的类,容器正常启动

困惑二:

ContextLoaderListener doc注释为:

Bootstrap listener to start up and shut down Spring's root {@link WebApplicationContext}...

Spring's root {@link WebApplicationContext},可以翻译为Spring的 顶级/根 WebApplicationContext吗?那是否有非root的呢?

也许我比较愚钝没能发现其中的奥秘,也可能我比较较真,非要打破沙锅问到底,思考了许久,还希望大牛能帮我答疑解惑。

共有 人打赏支持
hanzhankang
粉丝 155
博文 161
码字总数 82578
评论 (4)
一万
我可以大概讨论一下第二个问题,楼主的翻译是对的,ContextLoaderListener创建的是根应用上下文。

Spring framework可以创建一个或者多个应用上下文。一个应用上下文管理一组bean。这些上下文是可以有层次结构的,比如可以将applicationContext1设置为applicationContext2的父,子上下文可以访问父以上的上下文中的bean,而反过来不能访问。

ContextLoaderListener创建的根应用上下文是所有应用上下文的父。

一个常见的例子是Spring MVC 的DispatcherServlet 会创建自己的一个应用上下文,它可以访问到ContextLoaderListener创建的应用上下文中的bean,而根上下文却访问不到DispatcherServlet创建的应用上下文中的bean。所以DispatcherServlet可以访问到在ContextLoaderListener中注入的数据库相关的bean,而ContextLoaderListener应用上下文却访问不到DispatcherServlet创建的Controller、Service等bean。
一万
第一个问题,不是很明白了,猜想是不是有历史原因?因为与之相关的两个方法都被标注了过期。
请问楼主看的是哪个版本的源码?
我刚才查看了4.2.3版本的源码ContextLoaderListener里已经没有ContextLoader类的成员变量了。标注了过期的两个方法也被移除了。
hanzhankang

引用来自“一万”的评论

我可以大概讨论一下第二个问题,楼主的翻译是对的,ContextLoaderListener创建的是根应用上下文。

Spring framework可以创建一个或者多个应用上下文。一个应用上下文管理一组bean。这些上下文是可以有层次结构的,比如可以将applicationContext1设置为applicationContext2的父,子上下文可以访问父以上的上下文中的bean,而反过来不能访问。

ContextLoaderListener创建的根应用上下文是所有应用上下文的父。

一个常见的例子是Spring MVC 的DispatcherServlet 会创建自己的一个应用上下文,它可以访问到ContextLoaderListener创建的应用上下文中的bean,而根上下文却访问不到DispatcherServlet创建的应用上下文中的bean。所以DispatcherServlet可以访问到在ContextLoaderListener中注入的数据库相关的bean,而ContextLoaderListener应用上下文却访问不到DispatcherServlet创建的Controller、Service等bean。
赞!确实有父子关系,你得回答醍醐灌顶!
hanzhankang

引用来自“一万”的评论

第一个问题,不是很明白了,猜想是不是有历史原因?因为与之相关的两个方法都被标注了过期。
请问楼主看的是哪个版本的源码?
我刚才查看了4.2.3版本的源码ContextLoaderListener里已经没有ContextLoader类的成员变量了。标注了过期的两个方法也被移除了。
我的还是3.2.4,4.2.3现在还没有推。谢谢您哈!真赞!
×
hanzhankang
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: