如果正在閱讀本文的你是一名開發者,那么一定聽說過Eclipse和Intellij IDEA這兩款可以稱之為神器的集成開發環境(IDE)。
Eclipse以其代碼開源、插件眾多、擴展方便等特點,可以通過配置支持多種開發語言,用戶眾多。
Intellij IDEA則是分為社區版和專業版。由于是商業公司在維護和更新,因此專業版有更豐富的功能,使用起來更便捷,但如果只使用社區版,則一大塊功能不能使用。
當然,我們今天要討論的不是兩個IDE孰優孰劣,而是簡要分析下Tomcat在這兩個使用量巨大的IDE中是如何工作的。
- Eclipse
首先來看下Eclipse,通過配置將本地已經下載好的Tomcat添加到Server中。之后,在部署Web應用的時候,就可以選擇已經配置好的Tomcat。此時,通過啟動的Log,我們來看下其背后的原理。
仔細看上面的藍框內,是一個類似tomcat的webapps這個應用部署目錄的文件路徑,而且命令也是wtp.deploy。而wtp也是Eclipse的一個插件。我們再順著這個路徑,在本地打開看下。
這個是上層目錄,我們看到基本上除了Tomcat的bin目錄和lib目錄,剩下的差不多都在了。
其中conf下的文件有這些
可以看出和Tomcat的配置文件一個樣子。
再用上一篇文章里提到的jps命令查看下具體執行時的參數,就基本理解了
上面這張圖中,-D后面是JVM啟動時傳遞的參數,其中catalina.base,是代表Tomcat具體執行時,所有這些配置文件一類的資源具體查找的路徑,所有這些配置,在Tomcat啟動后,都會被解析得到,所以這些獨立位置的配置文件才能生效。
那如果要在一個IDE里跑多個Tomcat該怎么辦呢?
有了上面的分析你一定會說,so easy.只需要指定不同的catalina.base,在其對應的路徑下配置不同的文化的已 可以了。
對,影響一個操作系統中是否可以同時存在多個Tomcat,或者引申開來,即多個應用程序,無非是說端口這一類的資源沒有被占用即可。
而Tomcat,在本公眾號第三篇文章分析具體內部組件時看過,server.xml中可以配置Http通道,AJP通道這兩個是涉及到端口的,只要端口號使用不同的即可。
另外一個經常被忽略的是,Server下標簽下的port,默認是8005,這個也是會沖突的。需要注意下。
有了上面的分析,我們可以大致理清頭緒了。在Eclipse里,Tomcat的執行是通過指定不同的catalina.base來實現自定義不同的通道端口的配置,應用文件部署目錄等,從而可以在IDE內方便的使用之。
-
Intellij IDEA
下面再來看下Intellij IDEA。在啟動Tomcat時,Log一開始就能看到類似于下面的內容:
注意藍框中對應的內容,和在上面分析Catalina.base基本一致。為了嚴謹,還是要看一眼這個目錄內對應的內容
可以看出,實現思路和上面的分析基本一致,我們不再多談。
但這里和Eclipse的插件實現的區別是,這里并沒有指定wtp.deploy這個類似的屬性,所以在上圖的webapps目錄內并沒有我們要運行的應用的內容。那這個時候,IDEA內部是怎么實現應用的部署的呢?
在IDEA里,向tomcat部署一個應用,啟動時,其實并不會在本地的tomcat中找到該應用的目錄,或者實際運行的目錄下有該應用。仔細觀察發現,IDEA是通過Tomcat的MBean,動態的向tomcat增加了一個Context,即一個應用。這****樣直接指定了應用的路徑,訪問路徑等。
例如下面的調用鏈:
TCP Connection(2)-127.0.0.1@1379 daemon, prio=5, in group 'RMI Runtime', status: 'RUNNING'at org.springframework.web.context.ContextLoaderListener.<init>(ContextLoaderListener.java:98)at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1585)at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463)at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413)at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)at java.lang.Thread.run(Thread.java:745)
同時還能觀察到這樣的調用鏈,因為只有tomcat啟動之后,它的MBeanServer才能夠被訪問。所以如下是啟動一個空tomcat。
main@1, prio=5, in group 'main', status: 'RUNNING'at java.net.DualStackPlainSocketImpl.accept0(DualStackPlainSocketImpl.java:-1)at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)at java.net.ServerSocket.implAccept(ServerSocket.java:545)at java.net.ServerSocket.accept(ServerSocket.java:513)at org.apache.catalina.core.StandardServer.await(StandardServer.java:446)
at java.lang.reflect.Method.invoke(Method.java:483)at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:351)at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:485)
通過上面簡單的分析,IDE中Tomcat的具體執行原理,已經明了。