2013-04-11 45 views
21

Tôi đang làm việc trên API REST MVC của Spring. Tất cả mọi thứ hoạt động tốt, đó là tuyệt vời, nhưng tôi nhận thấy từ các bản ghi rằng mỗi khi tôi khởi động lại ứng dụng của tôi appContext tải hai lần: một lần khi tomcat tải tập tin chiến tranh, và lần thứ hai khi ứng dụng web được truy cập lần đầu tiên bởi một khách hàng.Ứng dụng web MVC mùa xuân: ngữ cảnh ứng dụng bắt đầu hai lần

tôi sẽ đưa ra một vài ví dụ:

Ngay sau khi tôi bắt đầu tomcat:

Apr 11, 2013 10:14:35 AM org.apache.catalina.core.StandardEngine start 
INFO: Starting Servlet Engine: Apache Tomcat/6.0.32 
Apr 11, 2013 10:14:36 AM org.apache.catalina.core.ApplicationContext log 
INFO: Initializing Spring root WebApplicationContext 
2013-04-11 10:14:36 INFO ContextLoader:273 - Root WebApplicationContext:  initialization started 
2013-04-11 10:14:36 INFO XmlWebApplicationContext:510 - Refreshing Root  WebApplicationContext: startup date [Thu Apr 11 10:14:36 EDT 2013]; root of context hierarchy 
2013-04-11 10:14:36 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions  from ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml] 
2013-04-11 10:14:36 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-general.xml] 
2013-04-11 10:14:37 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-db.xml] 
2013-04-11 10:14:37 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-security.xml] 
2013-04-11 10:14:37 INFO SpringSecurityCoreVersion:33 - You are running with Spring Security Core 3.1.3.RELEASE 
2013-04-11 10:14:37 INFO SecurityNamespaceHandler:59 - Spring Security 'config' module version is 3.1.3.RELEASE 

...

Và sau đó vào lúc này tôi thực hiện cuộc gọi API đầu tiên:

INFO: Initializing Spring FrameworkServlet 'mvc-dispatcher' 
2013-04-11 10:15:25 INFO DispatcherServlet:455 - FrameworkServlet 'mvc-dispatcher': initialization started 
2013-04-11 10:15:25 INFO XmlWebApplicationContext:510 - Refreshing WebApplicationContext for namespace 'mvc-dispatcher-servlet': startup date [Thu Apr 11  10:15:25 EDT 2013]; parent: Root WebApplicationContext 
2013-04-11 10:15:25 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml] 
2013-04-11 10:15:25 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-general.xml] 
2013-04-11 10:15:25 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-db.xml] 
2013-04-11 10:15:25 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [config-security.xml] 
2013-04-11 10:15:25 INFO SecurityNamespaceHandler:59 - Spring Security 'config' module version is 3.1.3.RELEASE 

Chắc chắn đây không phải là hành vi bình thường ?? web.xml của tôi trông như thế này:

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd ">

<display-name>REST API</display-name> 

<!-- Servlets --> 
<servlet> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> 
</context-param> 

<!-- filters --> 
<filter> 
    <filter-name>httpMethodFilter</filter-name> 
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>httpMethodFilter</filter-name> 
    <servlet-name>mvc-dispatcher</servlet-name> 
</filter-mapping> 
<filter> 
    <filter-name>etagFilter</filter-name> 
    <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>etagFilter</filter-name> 
    <servlet-name>mvc-dispatcher</servlet-name> 
</filter-mapping> 
<filter> 
    <filter-name>CompressingFilter</filter-name> 
    <filter-class>com.planetj.servlet.filter.compression.CompressingFilter</filter-class> 
    <init-param> 
     <param-name>debug</param-name> 
     <param-value>false</param-value> 
    </init-param> 
    <init-param> 
     <param-name>statsEnabled</param-name> 
     <param-value>false</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>CompressingFilter</filter-name> 
    <servlet-name>mvc-dispatcher</servlet-name> 
</filter-mapping> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 



<!-- listeners --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

+3

câu hỏi sau không có câu trả lời đã chọn, nhưng có thể câu hỏi vẫn có thể trợ giúp: http://stackoverflow.com/q/11409237/866172 – Jalayn

+0

câu trả lời đầu tiên được đưa ra không áp dụng cho tôi. Và câu trả lời thứ hai không làm việc cho tôi vì lý do tương tự nó không hoạt động cho OP – Hendrik

+0

@Jayayn upvote - về cơ bản bạn đã chỉ ra câu trả lời – ikumen

Trả lời

22

mvc-dispatcher đang tải 2x bởi vì đó là cách bạn đã xác định nó

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> 
</context-param> 

và tại

<servlet> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

cách tiếp cận đầu tiên thường là để tải một cái gì đó như một bối cảnh "toàn cầu" hoặc "gốc", nơi bạn có thể đặt tất cả các bean/tài nguyên được chia sẻ bởi nhiều bối cảnh servlet.

Cách tiếp cận thứ hai thường là tải ngữ cảnh servlet cụ thể. Khi số answer in this post đầu tiên chỉ ra, nó sử dụng quy ước đặt tên để tìm tệp cấu hình mvc-dispatcher, do đó bạn không cần xác định rõ ràng nó.

Bạn có mọi thứ được định nghĩa trong mvc-dispatcher-servlet.xml không? Nếu vậy, bạn có thể xóa

<context-param> 
    .. 
</context-param> 

định nghĩa, nếu không bạn có thể (mà tôi khuyên bạn nên duy trì trong tương lai) tách cấu hình của bạn thành nhiều tệp. Sau đó tải bean/tài nguyên được chia sẻ trong một cái gì đó giống như một root-context.xml (thông qua phương thức đầu tiên), và mỗi cấu hình servlet cụ thể dưới servletname-servlet.xml cho mỗi ngữ cảnh servlet.

+1

Tôi cuối cùng đã làm việc: Khi tôi xóa bối cảnh-param, nó phàn nàn rằng không có applicationContext.xml. Vì vậy, tôi tạo ra một, tôi di chuyển tất cả các của tôi từ mvc-dispatcher.xml đến applicationContext.xml. Sau đó, tôi đã có một số vấn đề bởi vì một số công cụ bị thiếu trong mvc-dispatcher.xml: Tôi đã thêm một ở đó và sau đó mọi thứ đã hoạt động. – Hendrik

+0

Tôi đã gặp vấn đề tương tự và được giải quyết bằng cấu hình sau (với DispatcherServlet): ' rest org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/rest-servlet.xml 1 ' –