`

Spring MVC的容器初始化过程。

阅读更多
先来看一下,初始化的大体流程:



然后,我们再来看一下,我们的控制器DispatcherServlet的类图及继承关系。



首先web.xml中定义了servlet,load-on-startup=1:



服务器启动的时候对该servlet进行初始化,调用HttpServletBean的init方法:



该方法里又会调用initSertlvetBean进行初始化。
initSertlvetBean这个方法是在FrameWorkServlet中定义的:



initWebApplicationContext是对Spring mvc容器的初始化。
而initFrameworkServlet();方法的实现是空的,可以由子类重写。

现在我们继续initWebApplicationContext():



WebApplicationContext parent =
	WebApplicationContextUtils.getWebApplicationContext(getServletContext());

这个步骤是得到的父context,也就是root context。

CreateWebApplicationContext(parent)是初始化Spring mvc的过程:



这个过程会生成一个 XmlWebApplicationContext 的实例,也就是Spring MVC的容器。
并通过下面的方法,设置父context,设置ServletContext等等信息。

Refresh方法会重启context,并初始化bean:



这个过程就是初始化bean的过程,我们可以简略的看一下,

得到并配置了BeanFactory.

注册了MessageSource。

注册了监听类ApplicationEventMulticaster

实例化所有的单例bean:finishBeanFactoryInitialization(beanFactory);

重点在于最后一步,finishRefresh();这一步会触发一个ApplicationEvent:
,进入 AbstractApplicationContext中的
protected void finishRefresh() {
	publishEvent(new ContextRefreshedEvent(this));
}

其中this是指XmlWebApplicationContext对象。

接下来继续调用AbstractApplicationContext中的:
public void publishEvent(ApplicationEvent event) {
	Assert.notNull(event, "Event must not be null");
	if (logger.isDebugEnabled()) {
		logger.debug("Publishing event in context [" + getId() + "]: " + event);
	}
	getApplicationEventMulticaster().multicastEvent(event);
	if (this.parent != null) {
		this.parent.publishEvent(event);
	}
}


发送者:XmlWebApplicationContext发布的这个event。XmlWebApplicationContext这个对象有个applicationEventMulticaster对象,实际为SimpleApplicationEventMulticaster对象。
public void multicastEvent(final ApplicationEvent event) {
	for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) {
		final ApplicationListener listener = (ApplicationListener)                    it.next();
		getTaskExecutor().execute(new Runnable() {
			public void run() {
				listener.onApplicationEvent(event);
			}
		});
	}
}

实际的消息就是在这里发布的。

接受者:接受者实际就是DispatcherServlet,因为DispatcherServlet实现了ApplicationListener接口 :
public interface ApplicationListener extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(ApplicationEvent event);

}


当发布了消息后,实际上就是调用了DispatcherServlet(实际这个方法在DispatcherServlet的父类FrameworkServlet中)的onApplicationEvent方法,我们来看一下onApplicationEvent的实现:
public void onApplicationEvent(ApplicationEvent event) {
	if (event instanceof ContextRefreshedEvent) {
		this.refreshEventReceived = true;
		onRefresh(((ContextRefreshedEvent) event).getApplicationContext());
	}
}


然后调用DispatcherServlet中的:
protected void onRefresh(ApplicationContext context) throws BeansException {
	initStrategies(context);
}

/**
 * Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize
* further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
	initMultipartResolver(context);
	initLocaleResolver(context);
	initThemeResolver(context);
	initHandlerMappings(context);
	initHandlerAdapters(context);
	initHandlerExceptionResolvers(context);
	initRequestToViewNameTranslator(context);
	initViewResolvers(context);
}


实际上,在进行initStrategies的时候,上有的bean都已经加载好了。

到此为止!!

wac = createWebApplicationContext(parent);结束了!!

接下来,将spring mvc的context注册到servletcontext:
getServletContext().setAttribute(attrName, wac);

到此为止!!
this.webApplicationContext = initWebApplicationContext();结束!

整个Spring MVC的加载结束了!


画外音:
解构Spring事件体系的具体实现
Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。AbstractApplicationContext拥有一个applicationEventMulticaster成员变量,applicationEventMulticaster提供了容器监听器的注册表。AbstractApplicationContext在refresh()这个容器启动方法中通过以下三个步骤搭建了事件的基础设施。我们在代码清单5 1中列出了refresh()内部的整个过程,为了阅读方便,在这里再次给出和事件体系有关的代码:



首先,在⑤处,Spring初始化事件的广播器。用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster就可以了,Spring会通过反射的机制将其注册成容器的事件广播器,如果没有找到配置的外部事件广播器,Spring自动使用SimpleApplicationEventMulticaster作为事件广播器。
在⑦处,Spring将根据反射机制,从BeanDefinitionRegistry中找出所有实现org.springframework.context.ApplicationListener的Bean,将它们注册为容器的事件监听器,实际的操作就是将其添加到事件广播器所提供的监听器注册表中。
在⑨处,容器启动完成,调用事件发布接口向容器中所有的监听器发布事件,在publishEvent()内部,我们可以看到Spring委托ApplicationEventMulticaster将事件通知给监听器。




  • 大小: 107.9 KB
  • 大小: 89.7 KB
  • 大小: 10.1 KB
  • 大小: 48.3 KB
  • 大小: 26.1 KB
  • 大小: 54 KB
  • 大小: 26.2 KB
  • 大小: 69.4 KB
  • 大小: 11.7 KB
0
0
分享到:
评论
1 楼 likui1314159 2016-01-14  
写的很好,学到了很多东西

相关推荐

    spring mvc 4.0

    14. **性能优化**:Spring MVC 4.0在内部做了许多性能优化,包括更快的DispatcherServlet初始化、更高效的HTTP方法映射等。 15. **兼容性与兼容性测试**:Spring MVC 4.0确保与各种Web容器的兼容性,如Tomcat、...

    spring mvc项目

    可用于分析spring mvc源码、spring mvc父子容器初始化流程、session和cookie机制、spring session等,也可以用于学习Java Web(servlet、filter、listener等)、spring源码等。 该项目使用servlet3.0规范,无web.xml...

    Spring MVC + Mybatis+Spring实现的个人博客系统

    wpblog.sql可能是数据库的初始化脚本,用于创建这些表结构并可能包含一些初始数据。MySQL是常用的开源关系型数据库管理系统,适用于中小型Web应用,具有良好的性能和稳定性。 **5. 文件结构** - `wpblog.sql`: 这个...

    Spring MVC框架简介和使用

    2. **初始化过程**: - 在 Web 容器启动时,会调用 `HttpServletBean` 的 `init()` 方法,初始化 Servlet 初始化参数。 - 接着调用 `FrameworkServlet` 的 `initServletBean()` 方法进行 Web 上下文初始化。 - ...

    spring MVC 初始启动blocking queue

    总结来说,`spring MVC 初始启动concurrent blocking queue`涉及的是在Spring MVC应用启动时使用`@PostConstruct`注解初始化并使用`BlockingQueue`进行并发控制和任务处理。这一技术可以帮助提高系统性能,特别是在...

    spring mvc

    - **初始化**:读取配置文件并初始化 Spring 容器。 - **请求处理**:处理所有进入系统的 HTTP 请求。 - **响应生成**:根据处理结果生成最终的 HTTP 响应。 #### 五、Spring MVC 双亲上下文说明 在 Spring MVC 中...

    Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)所有实验及实验报告.zip

    1. Spring框架的配置和使用,包括IoC容器的初始化、bean的定义和依赖注入。 2. Spring MVC的控制器定义、模型绑定、视图解析,以及处理HTTP请求的方法。 3. MyBatis的配置,SQL映射文件的编写,以及如何通过MyBatis...

    Spring,Spring MVC所需的jar包

    6. **spring-beans-4.1.5.RELEASE.jar**:包含Spring Bean的定义和管理,包括bean的创建、初始化、配置和销毁。它是Spring容器的核心,负责读取配置文件并管理bean的生命周期。 7. **spring-test-4.1.5.RELEASE.jar...

    Spring MVCSpring MVC基础.ppt

    DispatcherServlet也初始化了一个WebApplicationContext,它是Spring容器的一个特殊版本,专门用于Web应用。 2. **IoC(Inversion of Control)容器**:Spring MVC中的Controller组件是JavaBean,它们的实例化、...

    spring mvc中启动netty

    通常,Spring MVC使用Tomcat或其他Servlet容器来处理HTTP请求。但通过集成Netty,我们可以利用其非阻塞I/O的优势,提高应用性能。 3. **为什么要集成Netty** - **高性能**:Netty基于NIO,能更好地处理大量并发...

    OSGI整合Spring、Mybatis、Spring MVC实现一个登录应用案例

    总的来说,这个案例展示了OSGI的模块化优势,以及如何将Spring、Mybatis和Spring MVC集成到OSGI环境中,构建一个可维护、可扩展的登录应用。通过实践这样的案例,开发者可以更好地掌握这些技术在企业级开发中的应用...

    spring mvc demo

    这个"SpringMvc001"可能是项目初始化的目录,包含了一些基本的配置文件和样例代码。进一步学习时,我们可能会接触到以下主题: - **模型(Model)**:如何创建模型对象,以及如何使用`@ModelAttribute`将数据绑定到...

    Spring MVC深入学习之启动初始化过程

    Web容器初始化过程: 1. Web容器会读取`web.xml`部署描述符,根据其中的`&lt;listener&gt;`元素实例化监听器。如果监听器实现了ServletContextListener接口,那么会调用`contextInitialized()`方法。 2. 接下来,容器会...

    Spring MVC 4.2.4.RELEASE 中文文档v

    最后,文档还介绍了如何使用基于代码的 Servlet 容器初始化配置、如何使用 Java 编程配置或 MVC 命名空间进行定制化配置,以及如何进行高级定制以满足复杂的业务需求。 整个文档的翻译注记部分则提供了对翻译工作的...

    搭建Spring+Spring MVC+Hibernate开发框架

    然后,配置Spring的IoC容器,包括定义bean的实例化方式、初始化参数等。接着,设置Spring MVC的配置,如处理器映射器、视图解析器等。最后,配置Hibernate连接数据库的相关信息,包括数据源、实体类、映射文件等。 ...

    《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》_源代码.zip

    10. **Chapter 17** - Spring Boot:简述Spring Boot快速开发框架,如何简化Spring应用的初始化和配置。包括自动配置、起步依赖和命令行界面等内容。 这些章节覆盖了Java EE开发中的关键技术和最佳实践,从基础到...

    Spring MVC注解开发总结

    2. 在`ServletContainersInitConfig`类中,`getServletConfigClasses()`方法返回Spring MVC配置类`SpringMvcConfig`,确保Spring MVC容器的初始化。 五、其他配置 1. **避免Spring错误加载Spring MVC**:在`...

    spring mvc案例+配置+原理详解+架包

    1. **web.xml**:配置DispatcherServlet,包括初始化参数、拦截器、监听器等。 2. **spring-mvc.xml**:定义Bean、数据源、事务管理器、视图解析器、HandlerMapping和HandlerAdapter等。 四、Spring MVC 原理 1. *...

    【BAT必备】spring面试题,spring MVC面试题,spring boot面试题,spring cloud面试题

    Spring Boot是由Pivotal团队提供的全新框架,其设计目标是简化新Spring应用的初始搭建以及开发过程。Spring Boot采用自动化配置的方式,减少了开发者编写配置的工作量。 #### 2. 自动配置原理 Spring Boot自动配置...

Global site tag (gtag.js) - Google Analytics