@Service are constructed twice

I have a problem with my Spring application where my @Service classes are being created twice when the application starts. I know this is a problem with my configuration, as I've experienced it before, but what exactly am I doing wrong?

Is there anything fundamentally wrong with the way I've laid out my config, below? (I have omitted everything I deem to be irrelevant)

web.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 />

Answers


In addition to @GaryF's answer, there is a following beautiful solution for this problem (used in projects generated by 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:

Removing <context:component-scan> from myapp-config.xml means, that all your autodiscovered annotated beans are registered in DispatcherServlet's context (that is, the context loaded from myapp-servlet.xml).

However the recommended approach is to use servlet's context for presentation-specific things (such as controllers), and use the root context (myapp-config.xml) for the core services of your application. The solution above make this approach easy.

Regarding the practical considerations, when your core services are placed in servlet's application context, they can't be accessed from outside the scope of that servlet, for example, from another servlets (you may need to use another servlets to implement another access technologies) or filters (such as Spring Security filters). That's the reason for having core services in the root application context.


Need Your Help

Parse array output into table — Ruby Rails

ruby-on-rails ruby parsing

I am integrating someone else's library in Ruby/Rails that provides custom class which returns output from an API. This is an example of the code and output that comes when the class and custom met...

Init connection without sync using Bluetooth Low Energy in Android

android bluetooth sensor bluetooth-lowenergy

Is it possible to init a connection between my mobile phone and a sensor without synchronization between then?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.