這樣做的最終效果就是修改了項目的運(yùn)行方式。原先的運(yùn)行方式是以tomcat為中心,由tomcat來啟動和終止項目,現(xiàn)在是由我們的啟動程序 為中心,由啟動程序來負(fù)責(zé)啟動和終止項目。就相當(dāng)于現(xiàn)在流行的cs程序一樣,有單獨的啟動腳本,在啟動時進(jìn)行環(huán)境預(yù)初始化,更新程序以及其它操作,待完成 之后再進(jìn)行最終的項目啟動。
這篇主要講解如何使用embeded tomcat在代碼中進(jìn)行啟動和終止。網(wǎng)上的一般文章均為tomca5.x來做,這里使用了最新的tomcat7,因為tomcat7為embeded開 發(fā),單獨發(fā)布了org.apache.tomcat.embed包,以進(jìn)行獨立的embed開發(fā)。以下是相應(yīng)的maven包
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | < dependency > < groupId >org.apache.tomcat.embed</ groupId > < artifactId >tomcat-embed-core</ artifactId > < version >7.0.2</ version > </ dependency > < dependency > < groupId >org.apache.tomcat</ groupId > < artifactId >tomcat-util</ artifactId > < version >7.0.2</ version > </ dependency > < dependency > < groupId >org.apache.tomcat.embed</ groupId > < artifactId >tomcat-embed-jasper</ artifactId > < version >7.0.2</ version > </ dependency > < dependency > < groupId >org.apache.tomcat.embed</ groupId > < artifactId >tomcat-embed-logging-juli</ artifactId > < version >7.0.2</ version > </ dependency > |
使用了embed包中的core包,以及用于編譯jsp的jasper包,然后是工具類以及進(jìn)行上場記錄的logging-juli包。開始寫代碼:
1 2 3 4 5 6 7 | //設(shè)置工作目錄 String catalina_home = "d:/" ; Tomcat tomcat = new Tomcat(); tomcat.setHostname( "localhost" ); tomcat.setPort(startPort); //設(shè)置工作目錄,其實沒什么用,tomcat需要使用這個目錄進(jìn)行寫一些東西 tomcat.setBaseDir(catalina_home); |
上面使用了Tomcat類來進(jìn)行啟動類,在tomcat7以前均是使用一個叫Embed類來進(jìn)行啟動,在tomcat7之后,embed類被不建 議使用,而建議使用新的Tomcat類來進(jìn)行啟動了。然后設(shè)置主機(jī)名,端口,再設(shè)置一個工作目錄。這個工作目錄可以是任意目錄,主要是tomcat需要這 個目錄來記錄一些東西,比如記錄word信息,日志信息(如果配置了日志的話),以及臨時文件存儲等。
1 2 3 4 5 6 7 8 | //設(shè)置程序的目錄信息 tomcat.getHost().setAppBase( "e:/" ); // Add AprLifecycleListener StandardServer server = (StandardServer) tomcat.getServer(); AprLifecycleListener listener = new AprLifecycleListener(); server.addLifecycleListener(listener); //注冊關(guān)閉端口以進(jìn)行關(guān)閉 tomcat.getServer().setPort(shutdownPort); |
上面的代碼,首先設(shè)置我們的項目程序所在的appbase,即放項目代碼的地方。在通常的tomcat配置中,這個目錄一般是webapps。接 著設(shè)置一個listener,這個listener主要是負(fù)責(zé)啟動一些比如html native支持程序以及ipv6等信息配置(可以忽略)。接著是配置一個關(guān)閉的注冊端口,當(dāng)向這個端口發(fā)送信息時,就可以達(dá)到關(guān)閉tomcat的目的 (后面會講)。
1 2 3 4 5 6 7 8 9 | //加載上下文 StandardContext standardContext = new StandardContext(); standardContext.setPath( "/aa" ); //contextPath standardContext.setDocBase( "aa" ); //文件目錄位置 standardContext.addLifecycleListener( new Tomcat.DefaultWebXmlListener()); //保證已經(jīng)配置好了。 standardContext.addLifecycleListener( new Tomcat.FixContextListener()); standardContext.setSessionCookieName( "t-session" ); tomcat.getHost().addChild(standardContext); |
我們單獨使用了一個Context來為這個host添加上下文,tomcat本身提供一個方法tomcat.addWeb方法來添加項目包,不過 由于這里需要單獨設(shè)置一個tomcat的sessionName,所以使用與與tomcat.addWeb實現(xiàn)類似的方法來添加一個項目包。
以上代碼中有兩個需要注意的listener,一個是DefaultWebXmlListener,這個是由tomcat加載一些默認(rèn)的配置信 息,比如jspServlet,以及一些繁復(fù)的mime/type信息;加上這個,就不需要我們自己去寫這么多的配置,因為每個項目都需要這些。這個配置 與tomcat目錄下的conf/web.xml中的配置一樣,只不過這里是代碼化了。第二個是FixContextListener,這個主要是在項目 部署完后,將這個上下文設(shè)置為configured,表示已經(jīng)配置好了(不然,tomcat啟動時會報錯,即相應(yīng)上下文還未配置好)。
配置OK了之后,就是啟動tomcat了:
1 2 | tomcat.start(); tomcat.getServer().await(); |
啟動tomcat,并讓tomcat在關(guān)閉端口上監(jiān)聽。如果沒有最后一句,程序?qū)⒅苯咏Y(jié)束,保證監(jiān)聽之后,tomcat將一直監(jiān)聽關(guān)閉事件,待有關(guān)閉事件之后才結(jié)束當(dāng)前程序。所以如果想要關(guān)閉當(dāng)前的tomcat,只需要向關(guān)閉端口發(fā)送一些信息即可:
1 2 3 4 5 6 7 8 9 | private static void shutdown() throws Exception { Socket socket = new Socket( "localhost" , shutdownPort); OutputStream stream = socket.getOutputStream(); for ( int i = 0 ;i < shutdown.length();i++) stream.write(shutdown.charAt(i)); stream.flush(); stream.close(); socket.close(); } |
這樣即可達(dá)到關(guān)閉tomcat的目的。
實際上看整個項目代碼,項目代碼的運(yùn)行,就是一個配置一個基礎(chǔ)的server.xml(即tomcat目錄下的 conf/server.xml),先配置運(yùn)行端口,關(guān)閉監(jiān)聽端口;然后配置運(yùn)行的host以及添加一個上下文context,最后就開始運(yùn)行并開始監(jiān) 聽。對照這個程序,再看一下server.xml中的配置信息,就很容易明白以上這段代碼了。