springMVC的容器初始化过程
http://jwx0925.iteye.com/blog/1003424
·
先来看一下,初始化的大体流程:
然后,我们再来看一下,我们的控制器DispatcherServlet的类图及继承关系。
首先web.xml中定义了servlet,load-on-startup=1:
服务器启动的时候对该servlet进行初始化,调用HttpServletBean的init方法:
该方法里又会调用initSertlvetBean进行初始化。
initSertlvetBean这个方法是在FrameWorkServlet中定义的:
initWebApplicationContext是对Spring mvc容器的初始化。
而initFrameworkServlet();方法的实现是空的,可以由子类重写。
现在我们继续initWebApplicationContext():
这个步骤是得到的父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中的
其中this是指XmlWebApplicationContext对象。
接下来继续调用AbstractApplicationContext中的:
发送者:XmlWebApplicationContext发布的这个event。XmlWebApplicationContext这个对象有个applicationEventMulticaster对象,实际为SimpleApplicationEventMulticaster对象。
实际的消息就是在这里发布的。
接受者:接受者实际就是DispatcherServlet,因为DispatcherServlet实现了ApplicationListener接口 :
当发布了消息后,实际上就是调用了DispatcherServlet(实际这个方法在DispatcherServlet的父类FrameworkServlet中)的onApplicationEvent方法,我们来看一下onApplicationEvent的实现:
然后调用DispatcherServlet中的:
实际上,在进行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将事件通知给监听器。
然后,我们再来看一下,我们的控制器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将事件通知给监听器。
更多推荐
已为社区贡献1条内容
所有评论(0)