眾所周知,基本上javaee的配置文件都放在WEB-INF之下,javaee網頁工程默認讀取配置文件也只會在這個目錄下面讀,但經常看到一些javaee不知道是裝逼,還是因為用myeclipse自動生成,還是為了好管理的原因,將工程的配置文件移到其它文件夾,他們基本利用了SpringMVC的contextConfigLocation去完成這件事,contextConfigLocation下面常常也伴隨着classpath:這些東西。其實,這些也只是小小的玩意而已,你看懂就覺得這是無比簡單的事情了。
一、classpath
一切都要從classes這個文件夾和classpath說起。
打開你工程所在的工程目錄。你會發現有個.classpath在里面,而你在eclipse是看不到這玩意的。
默認的eclipse工程(不是myeclipse這些異端!)的.classpath是這樣的:
-
-
<classpath>
-
<classpathentry kind="src" path="src"/>
-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7.0_71">
-
<attributes>
-
<attribute name="owner.project.facets" value="java"/>
-
</attributes>
-
</classpathentry>
-
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0">
-
<attributes>
-
<attribute name="owner.project.facets" value="jst.web"/>
-
</attributes>
-
</classpathentry>
-
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
-
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
-
<classpathentry kind="output" path="build/classes"/>
-
</classpath>
除了一些con指明加載的系統包的的等屬性,主要是第三行,<classpathentry kind="src" path="src"/>,kind="src"這個節點指明將目錄工程下的src編譯。
至於編譯的去向,所有javaee工程只有一個地方,那就是WEB-INF下的classes文件夾。
不信你可以打開tomcat所在目錄的webapps下相應的javaee工程的WEB-INF看看,明顯是多了個classes文件夾。當然你必須像《【Javaweb】於Eclipse for JavaEE中編譯一個項目Tomcat下的webapps卻沒有的解決方法》(點擊打開鏈接)先設置eclipse將javaee工程編譯到tomcat,而不是eclipse自己的文件夾。
這里先說明一下,大家需要搞明白幾個概念:你eclipse是顯示你的工程目錄,工程目錄的東西經過編譯會去到tomcat的webapps之下,tomcat的webapps下的東西才是最終運行的成果。
可以看到eclipse的workspace,也就是工程空間的src里面的所有東西除了.java包括.xml,因為有.classpath指引,都被搬到tomcat的webapps下的編譯運行空間下的WEB-INF\classes,同時.java變成了編譯了之后的.class。
而WebContent的東西自然是照搬的,反過來,WebContent以外的東西,要是沒有.classpath是絕對不搬的,你絕對不會在tomcat的webapps下的編譯運行空間找到build、conf(我自己亂建的)這兩個在工程空間有的文件夾。
然而,我需要eclipse搬呢?那就對工程點右鍵->Properties->Java Build Path->Source->Add Folder...勾選Conf,即可。
你會發現Javaee的工程目錄變成這個樣子:
為了測試,在conf新建一個a.xml,你會發現編譯之后a.xml也搬到tomcat下的webapps了。
同時再打開工程目錄下的.classpath看看,你會發現變成在第4行,明顯多了一個src節點,同時指明我們剛才自己添加的文件夾啊:
-
-
<classpath>
-
<classpathentry kind="src" path="src"/>
-
<classpathentry kind="src" path="Conf"/>
-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7.0_71">
-
<attributes>
-
<attribute name="owner.project.facets" value="java"/>
-
</attributes>
-
</classpathentry>
-
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0">
-
<attributes>
-
<attribute name="owner.project.facets" value="jst.web"/>
-
</attributes>
-
</classpathentry>
-
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
-
< classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
-
<classpathentry kind="output" path="build/classes"/>
-
</classpath>
二、contextConfigLocation
那么這和SpringMVC的contextConfigLocation有什么關系呢?拿《【SpringMVC】Helloworld》(點擊打開鏈接)作為例子說這件事。
我覺得WEB-INF下太多的xml很礙眼,覺得就應該一個web.xml,要將SpringMVC-servlet.xml移到Java Resources的Conf文件夾,這樣好看點。
那就先像上面的操作在整個工程下先建一個conf文件夾,將SpringMVC-servlet.xml移到conf,同時要求eclipse編譯這個文件夾唄。工程目錄變成這樣:
但這個時候要是不做任何配置,SpringMVC還是只會搜索WEB-INF下的xml文件啊,根本無法完成工程目錄的初始化,於是contextConfigLocation就派上用場了,web.xml要改成這個樣子:
-
-
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns="http://java.sun.com/xml/ns/javaee"
-
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
-
version="3.0">
-
<!-- 要求初始化ContextLoaderListener設置的contextConfigLocation才能生效 -->
-
<listener>
-
< listener-class>
-
org.springframework.web.context.ContextLoaderListener
-
</ listener-class>
-
</listener>
-
<!-- 設置contextConfigLocation的參數,指明路徑 -->
-
<context-param>
-
< param-name>contextConfigLocation</param-name>
-
< param-value>
-
classpath:SpringMVC-servlet.xml
-
</ param-value>
-
</context-param>
-
<!-- 要求SpringMVC按照contextConfigLocation的設置的內容初始化 -->
-
<servlet>
-
< servlet-name>SpringMVC</servlet-name>
-
< servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-
< init-param>
-
< param-name>contextConfigLocation</param-name>
-
< param-value>
-
classpath:SpringMVC-servlet.xml
-
</ param-value>
-
</ init-param>
-
< load-on-startup>1</load-on-startup>
-
</servlet>
-
<servlet-mapping>
-
< servlet-name>SpringMVC</servlet-name>
-
< url-pattern>/</url-pattern>
-
</servlet-mapping>
-
</web-app>
要利用contextConfigLocation,你首先要在web.xml利用一個監聽器,啟動org.springframework.web.context.ContextLoaderListener這個SpringMVC這個自帶的公有類,然后再設置contextConfigLocation的要指明的初始化路徑,其中這里classpath:指的就是編譯之后,在Tomcat\工程根目錄\WEB-INF\classes文件夾,因為SpringMVC-servlet.xml被編譯之后,就會被放到classes文件夾啊。最后,還要要求,SpringMVC按照上面的設置的contextConfigLocation設置的內容啟動,格式就是這樣,基本等於將<context-param>節點的東西,在<init-param>照抄一次。
最后運行結果還是一模一樣的,證明上面設置生效:
這就是你在網上看到一大堆SpringMVC的所謂的“示例工程”,尤其靠MyEclipse配出來的SpringMVC,在web.xml寫一大堆,讀起來非常繞的的原因之一。
讓人繞了半天,tomcat啟動也慢了,還要讓人理解什么是classpath什么是contextConfigLocation,然后的目的就是為了將那堆,.xml移到conf文件夾!這不是裝逼是什么?什么好管理,個人看起來就是借口!明明人家的web.xml看起來可以很簡練,同時將SpringMVC-servlet.xml也作為SpringMVC核心的配置文件之一,放在WEB-INF我覺得根本就沒什么不好看的!你讓SpringMVC默認讀WEB-INF下的所有內容就是了!