- 浏览: 312859 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (221)
- J2SE心得 (4)
- 经典帖子 (8)
- 亲身经历 (9)
- SSH框架 (12)
- 数据库 (10)
- java基础知识 (41)
- java解惑 (17)
- 软件测试 (0)
- JSP (6)
- JavaScript (8)
- jQuery学习 (12)
- 硬件知识 (1)
- 工具类 (14)
- 面试专题 (4)
- Struts2专题(学习) (14)
- Spring源码分析专题(学习) (15)
- JavaScript专题(学习) (8)
- ExtJs专题(学习) (6)
- Java Web快速入门——全十讲 (10)
- web前台 (1)
- J2ME手机方面 (1)
- 积累整理 (1)
- MyEclipse工具篇 (10)
- oracle (1)
- Android基础 (1)
最新评论
-
youjianbo_han_87:
上传成功后,无法跳转到success页面,会报2038和404 ...
Struts2使用FlashFileUpload.swf实现批量文件上传 -
showzh:
...
MyEclipse 怎么安装SVN插件 -
wpf523:
赞一个啊,楼主加油
一些比较复杂的运算符(二) -
独步天下:
request.getSession().getAttribute() 和request.getSession().setAttribute() -
HelloJava1234:
thank you
怎么改变MyEclipse默认的jsp打开方式
上面我们分析了IOC容器本身的实现,下面我们看看在典型的web环境中,Spring IOC容器是怎样被载入和起作用的。
简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理器等各种中间层对象。在这个上下文的基础上,和web MVC相关还会有一个上下文来保存控制器之类的MVC对象,这样就构成了一个层次化的上下文结构。在web容器中启动Spring应用程序就是一个建立这个上下文体系的过程。Spring为web应用提供了上下文的扩展接口
WebApplicationContext:
- public interface WebApplicationContext extends ApplicationContext {
- //这里定义的常量用于在ServletContext中存取根上下文
- String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
- ......
- //对WebApplicationContext来说,需要得到Web容器的ServletContext
- ServletContext getServletContext();
- }
public interface WebApplicationContext extends ApplicationContext { //这里定义的常量用于在ServletContext中存取根上下文 String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT"; ...... //对WebApplicationContext来说,需要得到Web容器的ServletContext ServletContext getServletContext(); }
而一般的启动过程,Spring会使用一个默认的实现,XmlWebApplicationContext - 这个上下文实现作为在web容器中的根上下文容器被建立起来,具体的建立过程在下面我们会详细分析。
- public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
- /** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/
- public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
- public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
- public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
- //我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
- //对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
- beanDefinitionReader.setResourceLoader(this);
- beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
- initBeanDefinitionReader(beanDefinitionReader);
- loadBeanDefinitions(beanDefinitionReader);
- }
- protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
- }
- //使用XmlBeanDefinitionReader来读入bean定义信息
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
- String[] configLocations = getConfigLocations();
- if (configLocations != null) {
- for (int i = 0; i < configLocations.length; i++) {
- reader.loadBeanDefinitions(configLocations[i]);
- }
- }
- }
- //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml
- protected String[] getDefaultConfigLocations() {
- if (getNamespace() != null) {
- return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
- }
- else {
- return new String[] {DEFAULT_CONFIG_LOCATION};
- }
- }
- }
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { /** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/ public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; //我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { //对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { } //使用XmlBeanDefinitionReader来读入bean定义信息 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) { for (int i = 0; i < configLocations.length; i++) { reader.loadBeanDefinitions(configLocations[i]); } } } //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml protected String[] getDefaultConfigLocations() { if (getNamespace() != null) { return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else { return new String[] {DEFAULT_CONFIG_LOCATION}; } } }
对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用 ContextLoaderServlet或者ContextLoaderListener的启动时载入的Servlet来实例化Spring IOC容器 - 为什么会有两个不同的类来装载它呢,这是因为它们的使用需要区别不同的Servlet容器支持的Serlvet版本。但不管是 ContextLoaderSevlet还是 ContextLoaderListener都使用ContextLoader来完成实际的WebApplicationContext的初始化工作。这个ContextLoder就像是Spring Web应用程序在Web容器中的加载器booter。当然这些Servlet的具体使用我们都要借助web容器中的部署描述符来进行相关的定义。
下面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个 Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根上下文。当这个根上下文被载入后,它被绑定到web应用程序的ServletContext上。任何需要访问该ApplicationContext的应用程序代码都可以从WebApplicationContextUtils类的静态方法来得到:
WebApplicationContext getWebApplicationContext(ServletContext sc)
以Tomcat作为Servlet容器为例,下面是具体的步骤:
1.Tomcat 启动时需要从web.xml中读取启动参数,在web.xml中我们需要对ContextLoaderListener进行配置,对于在web应用启动入口是在ContextLoaderListener中的初始化部分;从Spring MVC上看,实际上在web容器中维护了一系列的IOC容器,其中在ContextLoader中载入的IOC容器作为根上下文而存在于 ServletContext中。
- //这里对根上下文进行初始化。
- public void contextInitialized(ServletContextEvent event) {
- //这里创建需要的ContextLoader
- this.contextLoader = createContextLoader();
- //这里使用ContextLoader对根上下文进行载入和初始化
- this.contextLoader.initWebApplicationContext(event.getServletContext());
- }
//这里对根上下文进行初始化。 public void contextInitialized(ServletContextEvent event) { //这里创建需要的ContextLoader this.contextLoader = createContextLoader(); //这里使用ContextLoader对根上下文进行载入和初始化 this.contextLoader.initWebApplicationContext(event.getServletContext()); }
通过ContextLoader建立起根上下文的过程,我们可以在ContextLoader中看到:
- public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
- throws IllegalStateException, BeansException {
- //这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。
- if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
- //直接抛出异常
- .........
- }
- ...............
- try {
- // 这里载入根上下文的父上下文
- ApplicationContext parent = loadParentContext(servletContext);
- //这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是
- //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文
- this.context = createWebApplicationContext(servletContext, parent);
- servletContext.setAttribute(
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
- ..........
- return this.context;
- }
- ............
- }
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException { //这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { //直接抛出异常 ......... } ............... try { // 这里载入根上下文的父上下文 ApplicationContext parent = loadParentContext(servletContext); //这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是 //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文 this.context = createWebApplicationContext(servletContext, parent); servletContext.setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); .......... return this.context; } ............ }
建立根上下文的父上下文使用的是下面的代码,取决于在web.xml中定义的参数:locatorFactorySelector,这是一个可选参数:
- protected ApplicationContext loadParentContext(ServletContext servletContext)
- throws BeansException {
- ApplicationContext parentContext = null;
- String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
- String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
- if (locatorFactorySelector != null) {
- BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
- ........
- //得到根上下文的父上下文的引用
- this.parentContextRef = locator.useBeanFactory(parentContextKey);
- //这里建立得到根上下文的父上下文
- parentContext = (ApplicationContext) this.parentContextRef.getFactory();
- }
- return parentContext;
- }
protected ApplicationContext loadParentContext(ServletContext servletContext) throws BeansException { ApplicationContext parentContext = null; String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); if (locatorFactorySelector != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); ........ //得到根上下文的父上下文的引用 this.parentContextRef = locator.useBeanFactory(parentContextKey); //这里建立得到根上下文的父上下文 parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; }
得到根上下文的父上下文以后,就是根上下文的创建过程:
- protected WebApplicationContext createWebApplicationContext(
- ServletContext servletContext, ApplicationContext parent) throws BeansException {
- //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext,
- //如果没有使用默认的。
- Class contextClass = determineContextClass(servletContext);
- .........
- //这里就是上下文的创建过程
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
- //这里保持对父上下文和ServletContext的引用到根上下文中
- wac.setParent(parent);
- wac.setServletContext(servletContext);
- //这里从web.xml中取得相关的初始化参数
- String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
- if (configLocation != null) {
- wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
- ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。
- wac.refresh();
- return wac;
- }
protected WebApplicationContext createWebApplicationContext( ServletContext servletContext, ApplicationContext parent) throws BeansException { //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext, //如果没有使用默认的。 Class contextClass = determineContextClass(servletContext); ......... //这里就是上下文的创建过程 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); //这里保持对父上下文和ServletContext的引用到根上下文中 wac.setParent(parent); wac.setServletContext(servletContext); //这里从web.xml中取得相关的初始化参数 String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocation != null) { wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation, ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。 wac.refresh(); return wac; }
初始化根ApplicationContext后将其存储到SevletContext中去以后,这样就建立了一个全局的关于整个应用的上下文。这个根上下文会被以后的DispatcherServlet初始化自己的时候作为自己ApplicationContext的父上下文。这个在对 DispatcherServlet做分析的时候我们可以看看到。
3.完成对ContextLoaderListener的初始化以后, Tomcat开始初始化DispatchServlet,- 还记得我们在web.xml中队载入次序进行了定义。DispatcherServlet会建立自己的ApplicationContext,同时建立这个自己的上下文的时候会从ServletContext中得到根上下文作为父上下文,然后再对自己的上下文进行初始化,并最后存到 ServletContext中去供以后检索和使用。
可以从DispatchServlet的父类FrameworkServlet的代码中看到大致的初始化过程,整个ApplicationContext的创建过程和ContextLoder创建的过程相类似:
- protected final void initServletBean() throws ServletException, BeansException {
- .........
- try {
- //这里是对上下文的初始化过程。
- this.webApplicationContext = initWebApplicationContext();
- //在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素
- initFrameworkServlet();
- }
- ........
- }
protected final void initServletBean() throws ServletException, BeansException { ......... try { //这里是对上下文的初始化过程。 this.webApplicationContext = initWebApplicationContext(); //在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素 initFrameworkServlet(); } ........ }
对initWebApplicationContext()调用的代码如下:
- protected WebApplicationContext initWebApplicationContext() throws BeansException {
- //这里调用WebApplicationContextUtils静态类来得到根上下文
- WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
- //创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
- WebApplicationContext wac = createWebApplicationContext(parent);
- ........
- if (isPublishContext()) {
- //把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。
- String attrName = getServletContextAttributeName();
- getServletContext().setAttribute(attrName, wac);
- }
- return wac;
- }
protected WebApplicationContext initWebApplicationContext() throws BeansException { //这里调用WebApplicationContextUtils静态类来得到根上下文 WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); //创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class; WebApplicationContext wac = createWebApplicationContext(parent); ........ if (isPublishContext()) { //把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。 String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); } return wac; }
其中我们看到调用了WebApplicationContextUtils的静态方法得到根ApplicationContext:
- public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
- //很简单,直接从ServletContext中通过属性名得到根上下文
- Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- .......
- return (WebApplicationContext) attr;
- }
- 然后创建DispatcherServlet自己的WebApplicationContext:
- protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
- throws BeansException {
- .......
- //这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS =
- //XmlWebApplicationContext.class;
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
- //这里配置父上下文,就是在ContextLoader中建立的根上下文
- wac.setParent(parent);
- //保留ServletContext的引用和相关的配置信息。
- wac.setServletContext(getServletContext());
- wac.setServletConfig(getServletConfig());
- wac.setNamespace(getNamespace());
- //这里得到ApplicationContext配置文件的位置
- if (getContextConfigLocation() != null) {
- wac.setConfigLocations(
- StringUtils.tokenizeToStringArray(
- getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里调用ApplicationContext的初始化过程,同样需要使用refresh()
- wac.refresh();
- return wac;
- }
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { //很简单,直接从ServletContext中通过属性名得到根上下文 Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); ....... return (WebApplicationContext) attr; } 然后创建DispatcherServlet自己的WebApplicationContext: protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) throws BeansException { ....... //这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS = //XmlWebApplicationContext.class; ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass()); //这里配置父上下文,就是在ContextLoader中建立的根上下文 wac.setParent(parent); //保留ServletContext的引用和相关的配置信息。 wac.setServletContext(getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()); //这里得到ApplicationContext配置文件的位置 if (getContextConfigLocation() != null) { wac.setConfigLocations( StringUtils.tokenizeToStringArray( getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里调用ApplicationContext的初始化过程,同样需要使用refresh() wac.refresh(); return wac; }
4. 然后就是DispatchServlet中对Spring MVC的配置过程,首先对配置文件中的定义元素进行配置 - 请注意这个时候我们的WebApplicationContext已经建立起来了,也意味着DispatcherServlet有自己的定义资源,可以需要从web.xml中读取bean的配置信息,通常我们会使用单独的xml文件来配置MVC中各个要素定义,这里和web容器相关的加载过程实际上已经完成了,下面的处理和普通的Spring应用程序的编写没有什么太大的差别,我们先看看MVC的初始化过程:
- protected void initFrameworkServlet() throws ServletException, BeansException {
- initMultipartResolver();
- initLocaleResolver();
- initThemeResolver();
- initHandlerMappings();
- initHandlerAdapters();
- initHandlerExceptionResolvers();
- initRequestToViewNameTranslator();
- initViewResolvers();
- }
protected void initFrameworkServlet() throws ServletException, BeansException { initMultipartResolver(); initLocaleResolver(); initThemeResolver(); initHandlerMappings(); initHandlerAdapters(); initHandlerExceptionResolvers(); initRequestToViewNameTranslator(); initViewResolvers(); }
5. 这样MVC的框架就建立起来了,DispatchServlet对接受到的HTTP Request进行分发处理由doService()完成,具体的MVC处理过程我们在doDispatch()中完成,其中包括使用Command模式建立执行链,显示模型数据等,这些处理我们都可以在DispatcherServlet的代码中看到:
- protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
- ......
- try {
- doDispatch(request, response);
- }
- .......
- }
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { ...... try { doDispatch(request, response); } ....... }
实际的请求分发由doDispatch(request,response)来完成:
- protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception {
- .......
- // 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。
- HandlerExecutionChain mappedHandler = null;
- ......
- try {
- //我们熟悉的ModelAndView在这里出现了。
- ModelAndView mv = null;
- try {
- processedRequest = checkMultipart(request);
- //这里更具request中的参数和映射关系定义决定使用的handler
- mappedHandler = getHandler(processedRequest, false);
- ......
- //这里是handler的调用过程,类似于Command模式中的execute.
- HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- .......
- //这里将模型数据通过视图进行展现
- if (mv != null && !mv.wasCleared()) {
- render(mv, processedRequest, response);
- }
- ........
- }
protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception { ....... // 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。 HandlerExecutionChain mappedHandler = null; ...... try { //我们熟悉的ModelAndView在这里出现了。 ModelAndView mv = null; try { processedRequest = checkMultipart(request); //这里更具request中的参数和映射关系定义决定使用的handler mappedHandler = getHandler(processedRequest, false); ...... //这里是handler的调用过程,类似于Command模式中的execute. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); ....... //这里将模型数据通过视图进行展现 if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); } ........ }
这样具体的MVC模型的实现就由bean配置文件里定义好的view resolver,handler这些类来实现用户代码的功能。
总结上面的过程,我们看到在web容器中,ServletContext可以持有一系列的web上下文,而在整个web上下文中存在一个根上下文来作为其它 Servlet上下文的父上下文。这个根上下文是由ContextLoader载入并进行初始化的,对于我们的web应用, DispatcherSerlvet载入并初始化自己的上下文,这个上下文的父上下文是根上下文,并且我们也能从ServletContext中根据 Servlet的名字来检索到我们需要的对应于这个Servlet的上下文,但是根上下文的名字是由Spring唯一确定的。这个 DispactcherServlet建立的上下文就是我们开发Spring MVC应用的IOC容器。
具体的web请求处理在上下文体系建立完成以后由DispactcherServlet来完成,上面对MVC的运作做了一个大致的描述,下面我们会具体就SpringMVC的框架实现作一个详细的分析。
发表评论
-
Spring源代码解析(十):Spring Acegi框架授权的实现
2009-12-01 11:05 1298我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2009-12-01 11:04 1156简单分析一下Spring Acegi的源代码实现: Servl ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2009-12-01 11:03 1205O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Hessian源码分析和Hack --让Hessian携带远程调用端的信息
2009-12-01 11:02 2307项目选定Hessian作为web se ... -
Spring源代码解析(七):Spring AOP中对拦截器调用的实现
2009-12-01 11:01 904前面我们分析了Spring AOP实现中得到Proxy对象的过 ... -
关于spring ioc容器的问题
2009-12-01 11:01 854在spring的源代码中,有org.springframewo ... -
Spring声明式事务管理源码解读之事务提交
2009-12-01 11:00 1017简介:上次说到spring声明式事务管理的事务开始部分,按流程 ... -
Spring源代码解析(六):Spring声明式事务处理
2009-12-01 11:00 1050我们看看Spring中的事务处理的代码,使用Spring管理事 ... -
Spring源代码解析(五):Spring AOP获取Proxy
2009-12-01 10:59 792下面我们来看看Spring的AOP的一些相关代码是怎么得到Pr ... -
Spring源代码解析(四):Spring MVC
2009-12-01 10:58 800下面我们对Spring MVC框架代码进行分析,对于webAp ... -
Spring声明式事务管理源码解读之事务开始
2009-12-01 10:57 686Spring声明式事务管理源码解读 简介:事务是所有企业应用系 ... -
Spring源代码解析(三):Spring JDBC
2009-12-01 10:56 1223下面我们看看Spring JDBC相关的实现, 在Spring ... -
Spring源代码解析(一):IOC容器
2009-12-01 10:55 1040在认真学习Rod.Johnson的 ... -
spring源码分析-XmlBeanFactory导读
2009-12-01 10:54 1682源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的, ...
相关推荐
Spring源代码解析(一):IOC容器.doc
Spring源代码解析(二):IoC容器在Web容器中的启动.doc
Spring源代码解析2:IoC容器在Web容器中的启动.doc Spring源代码解析3:Spring JDBC .doc Spring源代码解析4:Spring MVC .doc Spring源代码解析5:Spring AOP获取Proxy .doc Spring源代码解析6:Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
Spring源代码解析(二):IoC容器在Web容器中的启动 Spring源代码解析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
Spring源代码解析(二):ioc容器在Web容器中的启动 Spring源代码分析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理...
Spring源代码解析(二):ioc容器在Web容器中的启动 3.Spring源代码解析(三):Spring JDBC 4.Spring源代码解析(四):Spring MVC 5.Spring源代码解析(五):Spring AOP获取Proxy 6. Spring源代码解析(六):Spring...
Spring源代码解析(二):ioc容器在Web容器中的启动.doc Spring源代码分析(三):Spring JDBC.doc Spring源代码解析(四):Spring MVC.doc Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):...
简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...