@ Serwis są budowane dwa razy
Mam problem z moją wiosenną aplikacją, gdzie moje klasy @ Service są tworzone dwa razy po uruchomieniu aplikacji. Wiem, że jest to problem z moją konfiguracją, ponieważ doświadczyłem tego wcześniej, ale co dokładnie robię źle?
Czy jest coś zasadniczo złego w sposobie, w jaki przedstawiłem mój config, poniżej? (Pominąłem wszystko, co uważam za nieistotne)
Www.xml:
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/myapp-config.xml
/WEB-INF/myapp-security.xml
/WEB-INF/myapp-mvc.xml
</param-value>
</context-param>
<listener>
<listener-class>com.myapp.servlet.MyAppContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Myapp-servlet.xml
<context:component-scan base-package="com.myapp" annotation-config="true" />
<mvc:annotation-driven />
Myapp-config.xml
<context:component-scan base-package="com.myapp" annotation-config="true" />
<context:annotation-config />
3 answers
Oprócz odpowiedzi @ GaryF , istnieje następujące piękne rozwiązanie tego problemu (stosowane w projektach generowanych przez Spring Roo
):
Myapp-config.xml
<!-- Load everything except @Controllers -->
<context:component-scan base-package="com.myapp">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation"/>
</context:component-scan>
Myapp-servlet.xml
<!-- Load @Controllers only -->
<context:component-scan base-package="com.myapp" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller"
type="annotation"/>
</context:component-scan>
EDIT:
Usunięcie <context:component-scan>
z myapp-config.xml
oznacza, że wszystkie Twoje autodiscovered annotated beans są zarejestrowane w kontekście DispatcherServlet
(czyli w kontekście załadowanym z myapp-servlet.xml
).
Jednak zalecanym podejściem jest użycie kontekstu servleta dla elementy związane z prezentacją (takie jak kontrolery) i użyj głównego kontekstu (myapp-config.xml
) dla podstawowych usług aplikacji. Powyższe rozwiązanie ułatwia takie podejście.
Jeśli chodzi o względy praktyczne, kiedy podstawowe usługi są umieszczone w kontekście aplikacji servleta, nie mogą być dostępne spoza zakresu tego servleta, na przykład z innego servleta (może być konieczne użycie innego servleta do wdrożenia innej technologii dostępu) lub filtrów (takich jak Spring Security
filtry). To jest powód, dla którego usługi podstawowe są dostępne w kontekście aplikacji root.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:00:24
Jako dodatek do odpowiedzi podanej przez @ axtavt, chciałbym podać tutaj pasującą sprężynę JavaConfig.
W RootConfig.java
:
@ComponentScan(basePackages = { "com.myapp" },
excludeFilters = @Filter({Controller.class, Configuration.class}))
W WebMvcConfig.java
:
@ComponentScan(basePackages = { "com.myapp" },
useDefaultFilters = false, includeFilters = @Filter(Controller.class))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-05 08:58:09
Robisz dwa oddzielne skany komponentów nad tym samym pakietem bazowym. Usuń jedną z nich.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-02 09:25:34