@Service se construyen dos veces

Tengo un problema con mi aplicación Spring donde mis clases @Service se crean dos veces cuando se inicia la aplicación. Sé que esto es un problema con mi configuración, como lo he experimentado antes, pero ¿qué estoy haciendo exactamente mal?

¿Hay algo fundamentalmente malo con la forma en que he presentado mi configuración, a continuación? (He omitido todo lo que considero irrelevante)

web.xml:

 myapp org.springframework.web.servlet.DispatcherServlet 1   myapp /   contextConfigLocation  /WEB-INF/myapp-config.xml /WEB-INF/myapp-security.xml /WEB-INF/myapp-mvc.xml    com.myapp.servlet.MyAppContextListener   org.springframework.web.context.ContextLoaderListener  

myapp-servlet.xml

   

myapp-config.xml

   

Además de la respuesta de @ GaryF , existe una solución hermosa para este problema (utilizada en proyectos generados por Spring Roo ):

myapp-config.xml

     

myapp-servlet.xml

     

EDITAR:

Eliminar de myapp-config.xml significa que todos los beans anotados detectados automáticamente están registrados en el contexto de DispatcherServlet (es decir, el contexto cargado desde myapp-servlet.xml ).

Sin embargo, el enfoque recomendado es utilizar el contexto de servlet para elementos específicos de la presentación (como los controladores) y usar el contexto raíz ( myapp-config.xml ) para los servicios principales de su aplicación. La solución anterior hace que este enfoque sea fácil.

En cuanto a las consideraciones prácticas, cuando sus servicios centrales se ubican en el contexto de la aplicación de servlet, no se puede acceder desde fuera del scope de ese servlet, por ejemplo, desde otros servlets (puede necesitar usar otros servlets para implementar otras tecnologías de acceso) o filtros (como filtros Spring Security ). Esa es la razón para tener servicios básicos en el contexto de la aplicación raíz.

Como una adición a la respuesta que dio @axtavt, me gustaría dar la Spring JavaConfig coincidente aquí.

En RootConfig.java :

 @ComponentScan(basePackages = { "com.myapp" }, excludeFilters = @Filter({Controller.class, Configuration.class})) 

En WebMvcConfig.java :

 @ComponentScan(basePackages = { "com.myapp" }, useDefaultFilters = false, includeFilters = @Filter(Controller.class)) 

Estás haciendo dos escaneos de componentes por separado sobre el mismo paquete base. Eliminar uno de ellos.