SpringBoot2源码1-嵌入式Tomcat启动和@SpringBootApplication注解原理

1. 测试案例

1.1 引入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.5</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>8.5.64</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>8.5.64</version>
</dependency>

1.2 Servlet处理类

public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello tomcat");
    }
}

1.3 启动类

public class Main {

    public static void main(String[] args) throws LifecycleException {
        //自己写Tomcat的启动源码
        Tomcat tomcat = new Tomcat();


        tomcat.setPort(8888);
        tomcat.setHostname("localhost");
        tomcat.setBaseDir(".");

        Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");

        //给Tomcat里面添加一个Servlet
        Wrapper hello = tomcat.addServlet("/boot", "hello", new HelloServlet());
        hello.addMapping("/66"); //指定处理的请求

        tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制

        tomcat.getServer().await(); //服务器等待
    }
}

直接运行main方法,在浏览器中输入 http://localhost:8888/boot/66 ,输出为:

hello tomcat

以上只是一个Tomcat的启动并使用HelloServlet处理一个请求的案例。下面我们结合SpringMVC,看如何优雅的启动。

2. 嵌入式Tomcat启动SpringMVC

2.1 最简单的方法

public class Main {

    public static void main(String[] args) throws LifecycleException {
        //自己写Tomcat的启动源码
        Tomcat tomcat = new Tomcat();


        tomcat.setPort(8888);
        tomcat.setHostname("localhost");
        tomcat.setBaseDir(".");

        Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");

        //自己创建 DispatcherServlet 对象,并且创建ioc容器,DispatcherServlet里面有ioc容器
        DispatcherServlet servlet = new DispatcherServlet();
        Wrapper hello = tomcat.addServlet("/boot", "hello", servlet);

        tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制

        tomcat.getServer().await(); //服务器等待
    }
}

当然,如果使用这种方法启动,需要自己往容器中注入DispatcherServlet的各种初始化(九大组件等),所以这种方式比较麻烦,我们不采用这种方式。

2.2 Tomcat的SPI机制启动

利用tomcat的SPI启动机制,SPI机制下 QuickAppStarter生效创建 ioc容器配置DispatcherServlet等各种组件。可以参考Spring5源码14-SpringMVC入口及启动流程。代码如下:

Main.java:

public class Main {

    public static void main(String[] args) throws LifecycleException {
        //自己写Tomcat的启动源码
        Tomcat tomcat = new Tomcat();


        tomcat.setPort(8888);
        tomcat.setHostname("localhost");
        tomcat.setBaseDir(".");

        Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");

        tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制

        tomcat.getServer().await(); //服务器等待

    }

}

QuickAppStarter类:

/**
 * 最快速的整合注解版SpringMVC和Spring的
 */
public class QuickAppStarter extends AbstractAnnotationConfigDispatcherServletInitializer {
   @Override //根容器的配置(Spring的配置文件===Spring的配置类)
   protected Class<?>[] getRootConfigClasses() {
      return new Class<?>[]{SpringConfig.class};
   }

   @Override //web容器的配置(SpringMVC的配置文件===SpringMVC的配置类)
   protected Class<?>[] getServletConfigClasses() {
      return new Class<?>[]{SpringMVCConfig.class};
   }

   @Override //Servlet的映射,DispatcherServlet的映射路径
   protected String[] getServletMappings() {
      return new String[]{"/"};
   }

   @Override
   protected void customizeRegistration(ServletRegistration.Dynamic registration) {
//    super.customizeRegistration(registration);

//    registration.addMapping("");//
   }
}

启动后,在浏览器访问http://localhost:8888/boot/hello66 ,输出为:


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值