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