SpringMVC源码分析------基础知识(一)

代码地址
spring
觉得博主还可以给个Star

1.SpringMVC
SpringMVC是基于Servlet实现封装的。Servlet是sun公司提供的一门用于开发动态web资源的技术,通常我们也把实现了servlet接口的java程序,称之为Servlet。

2.创建webapp项目
File—>new project
在这里插入图片描述
在这里插入图片描述一定要添加此Maven Property(archetypeCatalog = internal)否则打开项目的时候可能会一直引入,引入的时间过长。

在我们的main目录下并没有发现java包,我们需要自己进行创建。但是创建之后需要进行配置(如果不进行配置则该包不是资源目录,无法擦创建java文件)。(配置如下)
在这里插入图片描述
第一点也说过基于servlet封装,所以需要引入相关的jar包,一共有两种形式,第一种是直接maven引入,还有一种是tomcat自带。
我们直接使用tomcat引入吧。
首先,添加tomcat启动
在这里插入图片描述在这里插入图片描述
之后找到自己的tomcat,并加入配置
在这里插入图片描述在右下角还需要配置。
在这里插入图片描述再添加tomcat自带的jar包
File--->
在这里插入图片描述
在这里插入图片描述我们会发现再这里多了两个jar包
在这里插入图片描述
然后就可以使用自己的tomcat运行了。
我们项目的第一步是,创建自己的servlet。
创建MyServlet.java

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 龙小虬
 * @date 2021/3/9 15:23
 */
public class MyServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        resp.getWriter().print("this is new Servlet");
    }
}

再在web.xml中配置过滤器信息
在这里插入图片描述
添加配置:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.servlet.MyServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

运行即可。

我们再来思考一下,servlet是否线程安全?
来验证一下吧。
将MyServlet.java代码进行修改:

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 龙小虬
 * @date 2021/3/9 15:23
 */
public class MyServlet extends HttpServlet {
    
    

    int count = 0;

    public MyServlet(){
    
    
        System.out.println("MyServlet无参构造执行。。。");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        count++;
        resp.getWriter().print("this is new Servlet,count:"+count);
    }
}

访问两次http://localhost:8080/SpringMVC_01_war/a,结果如下:
在这里插入图片描述这里我们可以看出此过滤器是单例,只进行了一次创建。右侧的count也会随着访问次数的增加而增加,在前面spring源码说过,单例是存在线程安全问题的。解决线程安全问题可以使用锁等等。

再来介绍几种不通过web.xml配置过滤器的方式。

  1. 使用@WebServlet
    直接在过滤器上加入@WebServlet注解。
package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 龙小虬
 * @date 2021/3/9 15:23
 */
@WebServlet("/")
public class MyServlet extends HttpServlet {
    
    

    int count = 0;

    public MyServlet(){
    
    
        System.out.println("MyServlet无参构造执行。。。");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        count++;
        resp.getWriter().print("this is new Servlet,count:"+count);
    }
}
  1. 实现ServletContainerInitializer
    创建MyHandlersTypes.java
package com.config;

/**
 * @author 龙小虬
 * @date 2021/3/9 16:41
 */
public class MyHandlersTypes {
    
    
}

创建MyServletContainerInitializer.java

package com.config;

import com.servlet.MyServlet;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
import java.util.Set;

/**
 * @author 龙小虬
 * @date 2021/3/9 16:29
 */
@HandlesTypes(MyHandlersTypes.class)
public class MyServletContainerInitializer implements ServletContainerInitializer {
    
    
    /**
     * 容器初始化加载一些操作,手动加载监听器、过滤器,第三方依赖信息
     * @param set 存储继承了MyHandlersTypes类所有子类的Class信息(注意只包含子类)
     * @param servletContext
     * @throws ServletException
     */
    @Override
    public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
    
    
        for (Class<?> s:set) {
    
    
            System.out.println(s);
        }
        // 手动加入过滤器
        ServletRegistration.Dynamic myServlet = servletContext.addServlet("myServlet", new MyServlet());
        // 添加过滤器的拦截目标
        myServlet.addMapping("/");
    }
}

分别创建PayUtils.java和MemberUtils.java

package com.config;

/**
 * @author 龙小虬
 * @date 2021/3/9 16:42
 */
public class MemberUtils extends MyHandlersTypes{
    
    
}
package com.config;

/**
 * @author 龙小虬
 * @date 2021/3/9 16:42
 */
public class PayUtils extends MyHandlersTypes{
    
    
}

运行结果会发现并没有配置成功。
针对于ServletContainerInitializer很特殊。他需要我们添加一个配置(resources/META-INF/servicesjavax.servlet.ServletContainerInitializer)
在这里插入图片描述在内部添加MyServletContainerInitializer.java的完整路径(com.config.MyServletContainerInitializer)。再次运行即可。

上面的配置是利用xml配置,也用了手动注册,还用了ServletContainerInitializer这个复杂的配置替代xml配置,但我们会发现现在大多数都是使用的SpringBoot,为什么我们使用SpringBoot的时候并没有web.xml呢?我们来一探究竟。

猜你喜欢

转载自blog.csdn.net/weixin_43911969/article/details/114585581