上下文相关的扫描组件过滤器


问题内容

我基于SpringMVC的Web应用程序通常使用2个上下文:MVC调度程序Servlet的Web应用程序上下文和父/根应用程序上下文。

<!-- the context for the dispatcher servlet -->
<servlet>
    <servlet-name>webApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
....
<!-- the context for the root/parent application context -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:root-context.xml</param-value>
</context-param>

在这些情况下,我使用组件扫描来加载所有bean。我的软件包是根据其用例(例如com.abc.registration,com.abc.login等)命名的,而不是根据技术层(例如com.abc.dao,com.abc.services等)命名的

现在我的问题是:为了避免某些类的重复扫描,为两个上下文过滤候选组件类是一种好习惯,例如,仅包括用于Web上下文扫描的MVC控制器,并包括所有其他组件(服务,dao
/在根应用程序上下文中?

<!-- servlet-context.xml -->
<context:component-scan base-package="com.abc.myapp" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!-- root-context.xml -->
<context:component-scan base-package="de.efinia.webapp">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

还是对于组件扫描避免这种重复既不重要,也没有必要吗?


问题答案:

我在两个方面喜欢您的解决方案:

  1. 您根据用例而不是层对类进行划分。如果您有一个web包含所有控制器的软件包,那么您就不会有问题。但是我仍然发现这种方法要好得多。

  2. 是的,您应该过滤类。显然,增加内存占用量不是问题,因为这是微不足道的(但是增加的启动时间可能很重要)。

但是,具有重复的Bean(控制器和服务Bean)可能会引入细微的错误和不一致之处。一些连接池已被初始化两次,一些启动挂钩运行了两次导致意外行为。如果您使用singleton范围,请保持原样。也许您不会立即遇到一些问题,但是遵守合同是很高兴的。

顺便说一句,也有一个<mvc:annotation-driven/>标签。