一、什么是嵌入式tomcat

嵌入式tomcat:非传统的部署方式,将tomcat嵌入到主程序中进行运行。

二、嵌入式tomcat的优点

灵活部署、任意指定位置、通过复杂的条件判断

三、Maven集成Tomcat启动分析

分析它的启动
Tomcat7RunnerCli是引导类,有个main方法
进一步分析
Tomcat7RunnerCli主要依靠Tomcat7Runner
分析结论
原来嵌入式启动就是调用了Tomcat的API来实现的

四、tomcat API接口

实现嵌入式Tomcat的基础
Tomcat本身提供了外部可以调用的API

Tomcat这个类(在Tomcat6或之前的版本,这个类叫做Embedded):
1.位于:org.apache.catalina.startup.Tomcat
2.该类由public修饰,外部可调用
3.该类有Server、Service、Engine、Connector、Host等属性
4.该类有init()、start()、stop()、destroy()等方法
5.了解这个类的时候结合server.xml来理解效果更佳

分析得出的结论:Tomcat类是外部调用Tomcat的接口(看源码的时候有注释的地方要特别注意)

五、手写嵌入式tomcat

分析:Tomcat单独启动的流程
这里写图片描述

结论:
使用Tomcat的API来实现:
① 新建一个Tomcat对象
② 设置Tomcat的端口
③ 设置Context目录
④ 添加Servlet容器
⑤ 调用Tomcat对象的Start()
⑥ 强制Tomcat等待//因为我们以下的demo是用main方法来启动的,为了防止main方法执行完,Tomcat也停了

手写嵌入式tomcat步骤:
第一步:引入依赖插件

<dependency>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
    </dependency>

第二步:建一个servlet(用于演示)

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

/**
 * @auther xiehuaxin
 * @create 2018-08-28 15:14
 * @todo
 */
public class DemoServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        out.println("<!DOCTYPE html><html>");
        out.println("<head>");
        out.println("<meta charset=\"UTF-8\" />");
        out.println("<title></title>");
        out.println("</head>");
        out.println("<body bgcolor=\"white\">");
        out.println("<h1>手写嵌入式Tomcat!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

第三步:手写Tomcat

import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;

/**
 * @auther xiehuaxin
 * @create 2018-08-28 15:16
 * @todo
 */
public class MyTomcat {

    public static void main(String[] args) throws LifecycleException {
        //1.把目录的绝对路径获取到
        String classPath = System.getProperty("user.dir");

        //2.新建一个Tomcat对象
        Tomcat tomcat = new Tomcat();

        //3.创建一个连接器
        Connector connector = tomcat.getConnector();
        //4.连接器有一个端口属性
        connector.setPort(9090);

        //5.设置Host
        Host host = tomcat.getHost();
        //6.设置Host的属性,可以参照Server.xml来进行理解
        host.setName("localhost");
        host.setAppBase("webapps");
        /**
         * tomcat.start();
         * 到上面这一步其实已经可以把tomcat起动了,只是现在启动里面没啥东西
         *
         * 八月 28, 2018 3:31:02 下午 org.apache.coyote.AbstractProtocol init
         * 信息: Initializing ProtocolHandler ["http-bio-9090"]
         * 八月 28, 2018 3:31:02 下午 org.apache.catalina.core.StandardService startInternal
         * 信息: Starting service Tomcat
         * 八月 28, 2018 3:31:02 下午 org.apache.catalina.core.StandardEngine startInternal
         * 信息: Starting Servlet Engine: Apache Tomcat/7.0.47
         * 八月 28, 2018 3:31:02 下午 org.apache.coyote.AbstractProtocol start
         * 信息: Starting ProtocolHandler ["http-bio-9090"]
         */

        //7.把class加载进来,把启动的工程加入进来了
        Context context = tomcat.addContext(host,"/",classPath);

        if(context instanceof StandardContext) {
            StandardContext standardContext = (StandardContext) context;
            //要给一个默认的web.xml文件
            standardContext.setDefaultContextXml("D:\\soft\\tomcat\\apache-tomcat-8.0.30-windows-x64\\apache-tomcat-8.0.30\\conf\\web.xml");
            //把server设置进去
            Wrapper wrapper = tomcat.addServlet("/","DemoServlet",new DemoServlet());
            wrapper.addMapping("/nelson");
        }
        tomcat.start();
        //强制Tomcat Server等待,避免main线程执行结束后关闭
        tomcat.getServer().await();
    }
}

运行结果截图:
这里写图片描述

其他

① 面试的时候能说得出来“Tomcat里有还有一个Tomcat的类,这个类的可以做嵌入式的启动,不需要再下载tomcat和做传统的复杂的部署”。

② Maven如何集成tomcat?
Maven中引入了tomcat的插件

org.apache.tomcat.maven
tomcat7-maven-plugin
2.2

插件运行:选择pom.xml,右键—–>选择Run As—–>Maven build—–>在Goals框加入命令tomcat7:run

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐