1. 程式人生 > >Tomcat(二):手寫嵌入式tomcat

Tomcat(二):手寫嵌入式tomcat

一、什麼是嵌入式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