Spring MVC源码分析(一)-组件功能分析

一、Servlet

Spring MVC中核心Servlet(DispatcherServlet)的继承结构 图标(C)表示是类,而图标(I)表示接口

     

而上图的其中HttpServlet、GenericServlet、Servlet、ServletConfig 都在 javax-servlet-api-x.x.x.jar里面(x.x..x表示版本(如4.0.0))

而其他的类或接口都在 spring-xx.jar里面

   1、Servlet

         Servlet3.1的Servlet的接口代码如下:



package javax.servlet;

import java.io.IOException;

public interface Servlet {

    public void init(ServletConfig config) throws ServletException;
    public ServletConfig getServletConfig();
    public void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;
    public String getServletInfo();
    public void destroy();
}

     init方法在容器启动时被容器调用(当load-on-startup设置为负数或者不设置时会在Servlet第一次用到时才被调用),

     service方法用于具体处理一个请求;

     getServiceInfo方法可以获取一些Servlet相关的信息,如作者,版权等,可以自定义实现,默认返回空字符串。

     destroy方法 销毁Servlet,只会调用一次。

     init方法被调用时传入ServletConfig类型参数。

      web.xml配置Spring MVC Servlet:

	<!-- Spring MVC Servlet -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath*:spring/spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

  init-param标签配置参数通过ServletConfig来保持的。

	<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:/applicationContext.xml
        </param-value>
    </context-param>

 context-param配置的contextConfigLocation配置到了ServletContext中。

在servlet中获取相对应的值:

String contextLocation = getServletConfig().getServletContext().getInitParameter("contextConfigLocation");

String servletLocation = getServletConfig().getInitParameter("contextConfigLocation");

定义Spring MVC的Servlet时制定文件位置的contextConfigLocation参数就保存在ServletConfig中。 

  Servlet通过文件xml配置,解使xml时会把配置项设置到StandardWrapper中。

StandardWrapper继承了ServletConfig接口,代码如下:


package javax.servlet;

import java.util.Enumeration;

 public interface ServletConfig {
    public String getServletName();
    public ServletContext getServletContext();
    public String getInitParameter(String name);
    public Enumeration<String> getInitParameterNames();

}

1、-->StandardWrapper类调用initServlet方法

      -->GenericServlet类(Servlet)调用init方法

       -->HttpServletBean类调用init()方法

       而StandardWrapper类在Tomcat中,StandardWrapper类是Tomcat中的Wrapper接口的实现类,而Wrapper是Container容器的子容器之一。每一个Wrapper封装着一个Servlet .

        也就是Servlet的init方法调用具体实现时在StandardServlet类的intiServlet方法中具体实现的。

         ServletContext时Tomcat中的Context的门面类ApplicationContextFacade.

                                            Tomcat中的 Container容器装配结构图

           

  2、HttpServlet

          

         

HttpServlet基于Http协议的Servlet基类,HttpServlet重写了service方法。具体处理交给了doPost、doPut、doGet和doDelete等方法处理

package javax.servlet.http;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.*;


public abstract class HttpServlet extends GenericServlet
{
    private static final String METHOD_DELETE = "DELETE";
    private static final String METHOD_HEAD = "HEAD";
    private static final String METHOD_GET = "GET";
    private static final String METHOD_OPTIONS = "OPTIONS";
    private static final String METHOD_POST = "POST";
    private static final String METHOD_PUT = "PUT";
    private static final String METHOD_TRACE = "TRACE";

    private static final String HEADER_IFMODSINCE = "If-Modified-Since";
    private static final String HEADER_LASTMOD = "Last-Modified";
    
    private static final String LSTRING_FILE =
        "javax.servlet.http.LocalStrings";
    private static ResourceBundle lStrings =
        ResourceBundle.getBundle(LSTRING_FILE);
   
    
    public HttpServlet() { }
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }


    protected long getLastModified(HttpServletRequest req) {
        return -1;
    }
    protected void doHead(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        NoBodyResponse response = new NoBodyResponse(resp);
        
        doGet(req, response);
        response.setContentLength();
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }

    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_put_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }


    prot
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值