Spring框架中context-param與servlet中init-param的contextConfigLocation的區別
積累,小白也可成為大神
最近在使用spring這一個框架做定時任務的時候,發現一個問題。當我們不在瀏覽器中呼叫一下我們的介面,是不會自動執行定時檔案的,這個原因是什麼呢?剛開始的時候,使我費解了很長事件,不知道問題出現再哪裡。但是當冷靜下來思考一下的時候,發現了問題出現再servlet中。接著,對它進行分析一下。
在springmvc這個框架中,一般spring預設存在兩個配置檔案,一個是applicationContext.xml,另一個是spring-servlet.xml。一般情況下,我們會把註解中的自動載入,定時器的自動載入等內容寫在spring-servlet.xml。然後把spring-servlet.xml,放在web.xml檔案下的servlet中進行初始化。例如:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value> classpath:spring-servlet.xml</param-value>
</init-param>
</servlet>
而將applicationContext.xml配置成全域性的形式,例如:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:spring-servlet .xml
</param-value>
</context-param>
對比一下,就會發現問題所在。spring-servlet.xml因為被配置在servlet的初始化過程中,所以如果不初始化servlet,那麼spring-servlet.xml是不會被發現的。如果我們將定時器的註解載入過程放在spring-servlet.xml中,如果不進行頁面的重新整理,是不會經過DispatcherServlet這個跳轉器的,所以也就不會載入spring-servlet.xml檔案,所以定時任務可能就不會被觸發。如果經過了這個DispatcherServlet這個跳轉器,即被初始化。所以定時任務才會被執行。
而如果將註解的自動載入內容,例如:
<context:component-scan base-package="control"/><mvc:annotation-driven />
放在了applicationContext.xml中。因為當伺服器執行起來之後,就會自動載入applicationContext.xml檔案,所以定時任務會立即被執行。
如果想要避免這種錯誤的發生,最簡單的方法就是。將需要啟動伺服器之後,立刻就要知道的內容,例如
<context:component-scan base-package="control"/>
<mvc:annotation-driven />
,加到applicationContext.xml檔案中即可。
另一種方法就是,將spring的所有配置檔案都放在context-param(上下文引數)中進行載入,例如:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:spring-servlet.xml
</param-value>
</context-param>
這樣所有的問題就可以解決。
總結
從上面出現的問題,我們不難發現。spring框架在載入web配置檔案的時候。首先載入的是context-param配置的內容,而並不會去初始化servlet。只有進行了網站的跳轉,經過了DispatcherServlet的導航的時候,才會初始化servlet,從而載入init-param中的內容。