我是靠谱客的博主 高挑小懒虫,最近开发中收集的这篇文章主要介绍模拟SpringMvc的实现(一)准备环境技术路线具体实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

SpringMvc是一个很优秀的框架,做web开发的基本都会用到。它整个框架的本质其实就是一个servlet。
关于mvc的整体介绍可以参考我之前的另一篇博客
http://blog.csdn.net/z344310362/article/details/51387724

准备环境

需要servlet3.0以上的依赖包。
web容器需要需用支持servlet3.0的(如tomcat7以上)

技术路线

  1. servlet
    mvc的本质是一个servlet,放到mvc的框架里面,核心就是一个DispatcherServlet类。
    这个类的继承关系如下:

    DispatcherServlet->FrameworkServlet->HttpServlet->HttpServlet

    从最后的一个HttpServlet中我们可以看到,虽然它层层隐藏,但是最终就是一个servlet。
  2. mvc核心业务
    mvc的核心业务就是servlet的核心,它主要就是:

    • 初始化业务:init()->initStrategies()
      在初始化中mvc主要是在initStrategies() 这个方法里面完成了9个核心组件的注册。
    • 请求处理:service()->doDispatch()
      在处理请求中mvc的入口是在doDispatch() 方法里面的。这个方法中主要是根据请求匹配到对应的handler,进行具体的业务处理。
  3. servlet注册
    在这个demo中我们用到了servlet3.0以上才有的一个接口ServletContainerInitializer
    继承了这个接口后我们容器启动后会调用这个接口里面提供的onStartup 方法。这样我们的一些初始化动作就可以在里面完成,包括servlet的动态注册。
    我们的DispatcherServlet也就可以在里面注册了(以前注册一个servlet我们是在web.xml里面配置的),在这个demo中我们可以摒弃掉web.xml。

具体实现

  1. 结构预览
    这里写图片描述
    目前只是实现了一个大体的结构,所以很简单。红色矩形的2个类就是这个demo的核心类。

  2. MyContainerInitializer介绍

    @HandlesTypes({WebApplicationInitializer.class})
    public class MyContainerInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
    System.out.println("MyContainerInitializer start");
    LinkedList initializers = new LinkedList();
    Iterator var4;
    if(webAppInitializerClasses != null) {
    var4 = webAppInitializerClasses.iterator();
    while(var4.hasNext()) {
    Class initializer = (Class)var4.next();
    if(!initializer.isInterface() && !Modifier.isAbstract(initializer.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(initializer)) {
    try {
    initializers.add((WebApplicationInitializer)initializer.newInstance());
    } catch (Throwable var7) {
    throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
    }
    }
    }
    if(initializers.isEmpty()) {
    servletContext.log("No WebApplicationInitializer types detected on classpath");
    } else {
    servletContext.log(initializers.size() + "WebApplicationInitializers detected on classpath");
    var4 = initializers.iterator();
    while(var4.hasNext()) {
    WebApplicationInitializer initializer1 = (WebApplicationInitializer)var4.next();
    initializer1.onStartup(servletContext);
    }
    }
    }
    }
    }

    这个类实现了ServletContainerInitializer这个接口,所以容器在启动时会调用里面的onStartup 方法。
    类声明的上面有一个@HandlesTypes({WebApplicationInitializer.class})
    它标明了WebApplicationInitializer这个类的子类在启动时会添加到onStartup 方法里面的一个参数Set<Class<?>> webAppInitializerClasses 里面。这样我们通过这个参数就可以对这些类进行调用。

    public interface WebApplicationInitializer {
    void onStartup(ServletContext var1) throws ServletException;
    }
  3. DispatcherServletInitializer介绍
    这个类的主要用途是将DispatcherServlet动态注册到我们的容器里面。

    public class DispatcherServletInitializer implements WebApplicationInitializer{
    public static final String DEFAULT_SERVLET_NAME = "dispatcher";
    @Override
    public void onStartup(ServletContext var1) throws ServletException {
    this.registerDispatcherServlet(var1);
    }
    protected void registerDispatcherServlet(ServletContext servletContext) {
    ServletRegistration.Dynamic registration = servletContext.addServlet(DEFAULT_SERVLET_NAME, new DispatcherServlet());
    registration.setLoadOnStartup(1);
    registration.addMapping("*.do");
    }
    }

    这个类实现了WebApplicationInitializer 这个接口,所以它在启动的时候会被添加到2中的MyContainerInitializer 里面的onstartup里面。Set<Class<?>>
    这个类里面用到了ServletRegistration.Dynamic 来动态注册servlet。

  4. DispatcherServlet介绍
    看似复杂的springmvc被剥光后就剩下一个DispatcherServlet类。

    /**
    * @Author:zhourj
    * @Description:
    * @Date Create in 12:01 2016/11/13 0013
    */
    public class DispatcherServlet extends FrameworkServlet {
    protected void onRefresh() {
    this.initStrategies();
    }
    /**
    * 初始化MVC的9个组件
    */
    protected void initStrategies() {
    /*this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);*/
    }
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    this.doDispatch(request,response);
    }
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    System.out.println("mvc 分配请求");
    PrintWriter writer = null;
    try {
    writer = response.getWriter();
    // response.setContentLength(responseContent.length());
    writer.write("mvc处理结果");
    writer.flush();
    writer.close();
    } catch (Exception e) {
    } finally {
    if (writer != null) {
    writer.close();
    }
    }
    }
    }

    目前我基本没有实现这个类的什么方法,就是展示他的大体结构。
    从3中的代码registration.addMapping("*.do"); 我们知道这个servlet将所有”.do”的请求的包含给自己处理了。所有要让我们的mvc响应到的请求就必需以“.do”结尾。然后具体请求的分配就交给doDispatch 这个方法处理,它具体会利用HandlerMappings组件来帮忙寻找具体的handler。

  5. pom.xml

    <dependencies>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>
    <build>
    <finalName>test</finalName>
    <resources>
    <resource>
    <directory>src/main/java</directory>
    <excludes>
    <exclude>**/*.java</exclude>
    </excludes>
    </resource>
    </resources>
    </build>

    这里我只用到了servlet3.1的一个依赖。里面resource的配置是将根路径里面的配置文件拷贝到class里面。这里主要是我用IDEA的一个坑,没自动帮我拷贝进去。
    这里写图片描述
    这里需要注意到的要有这个META-INF,里面要有这个一个文件。这样启动的时候2中的MyContainerInitializer onstartup方法才能进去。这是servlet中规定的。


本文章主要是个人学习归纳
源代码下载:http://download.csdn.net/detail/z344310362/9694233

最后

以上就是高挑小懒虫为你收集整理的模拟SpringMvc的实现(一)准备环境技术路线具体实现的全部内容,希望文章能够帮你解决模拟SpringMvc的实现(一)准备环境技术路线具体实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部