springboot启动时自行方法_springboot整合springmvc源码分析(1)前言

springboot是怎么做到内嵌tomcat,而不需要去部署项目到tomcat的,在分析springboot整合springmvc前,我们先来说说一点关于tomcat的东西,我们这里不需要下载tomcat服务,只需要new 一个tomcat 即可,下面我们来一个例子看看

org.apache.tomcat.embed      tomcat-embed-core      8.5.28javax.servlet            javax.servlet-api            3.1.0provided
b41b7f324de9440f9db03098f69faf6e
public class App {    public static void main(String[] args) throws LifecycleException, ServletException {        Tomcat tomcat = new Tomcat();        tomcat.setPort(8989);        tomcat.addWebapp("/","d:omcat");        tomcat.start();        tomcat.getServer().await();    }}
b41b7f324de9440f9db03098f69faf6e
 
b41b7f324de9440f9db03098f69faf6e

我们只需要这样做就完全可以启动一个tomcat了

d8e26dfba2ce48cab1cfc41ebba1776f
b41b7f324de9440f9db03098f69faf6e

tomcat在启动过程中呢会自动加载实现了该接口ServletContainerInitializer的类,其中涉及到spi(不懂的自行百度),tomcat启动过程中会通过spi去加载实现ServletContainerInitializer的类的onStartup方法,spi默认文件结构:META-INF/services/javax.servlet.ServletContainerInitializer

ef06e0a2fd2c4097994f835999ec8d04
b41b7f324de9440f9db03098f69faf6e

只需要这样写即可完成spi的调用,该文件内容写上自己实现ServletContainerInitializer的类全名:

46e61f5111da4cbe94715c2b00528961
b41b7f324de9440f9db03098f69faf6e

我们下面来试一下这种写法

1.实现ServletContainerInitializer接口:

@HandlesTypes(MyWebApplicationInitializerInterFace.class)public class MyServletContainerInitializer implements ServletContainerInitializer {    public void onStartup(Set> c, ServletContext ctx) throws ServletException {        System.out.println("MyServletContainerInitializer.onStartup");        for(Class> clz : c){            System.out.println("MyServletContainerInitializer.onStartup:"+clz.getName());            try {                MyWebApplicationInitializerInterFace webApplicationInitializer = (MyWebApplicationInitializerInterFace)clz.newInstance();                webApplicationInitializer.onStartup(ctx);            } catch (Throwable ex) {                throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);            }        }    }}
b41b7f324de9440f9db03098f69faf6e

这里有个@HandlesTypes注解,该注解意思是将所有MyWebApplicationInitializerInterFace.class实现该接口的类注入到onStartup方法里的参数Set> c里;

2.编写MyWebApplicationInitializerInterFace接口:

public interface MyWebApplicationInitializerInterFace {    void onStartup(ServletContext ctx);}
b41b7f324de9440f9db03098f69faf6e

3.实现MyWebApplicationInitializerInterFace接口:

public class MyWebApplicationInitializer implements MyWebApplicationInitializerInterFace{    public void onStartup(ServletContext ctx) {        ServletRegistration.Dynamic registration = ctx.addServlet("demo", new HttpServlet() {            @Override            public void init() throws ServletException {                super.init();                System.out.println("====init");            }            @Override            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {                System.out.println("====doGet"+req.getRequestURI());                resp.getWriter().println("hello tomcat!");            }        });        registration.setLoadOnStartup(1);        registration.addMapping("*.do");    }}
b41b7f324de9440f9db03098f69faf6e

4.再次启动我们前面编写的tomcat的类App:

ff60cee200d843f29d10770971af257a
b41b7f324de9440f9db03098f69faf6e

你会发现打印我我们加的日志,这就表明我们spi调用时成功的,MyWebApplicationInitializer 是自己写的添加一个HttpServlet放入tomcat中,注意App类这里tomcat.addWebapp("/","d:omcat");写成tomcat.addContext("/","d:omcat")也是可以,但是你会发现写成tomcat.addContext不会spi加载,写成tomcat.addWebapp实则是告诉tomcat我们是web服务

5.浏览器访问:

1fb01aaae4f848558edfa1b1b08a155f
b41b7f324de9440f9db03098f69faf6e

写到这里,不知大家能不能感受到springboot整合springmvc是否也是借此方式进行的呢?MyWebApplicationInitializer里添加的HttpServlet就好比springmvc的核心控制器DispatcherServlet往tomcat加,我们现在这么猜想完全是有可能的,带着这个猜想我们下一章来展开进行源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值