依赖于上下文的扫描组件过滤器

时间:2011-09-30 11:43:11

标签: spring spring-mvc

我的基于SpringMVC的webapp通常使用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 / repositorie)?

<!-- 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>

或者为组件扫描避免这种重复既不重要也不必要?

2 个答案:

答案 0 :(得分:2)

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

  1. 您可以根据用例而不是图层来划分类。如果您有一个包含所有控制器的web个包,那么您就不会遇到问题。但我仍然发现这种方法更好。

  2. 是的,你应该过滤课程。显然,增加内存占用不是问题,因为这是边缘的(但启动时间增加可能很重要)。

  3. 但是,重复的bean(控制器和服务bean)可能会引入细微的错误和不一致。某些连接池已初始化两次,某些启动挂钩运行两次导致意外行为。如果您使用singleton范围,请保持原样。也许你不会马上遇到一些问题,但遵守合同是很好的。

    BTW请注意,还有一个<mvc:annotation-driven/>标记。

答案 1 :(得分:1)

确实,这是一种很好的做法。父应用程序上下文中不应包含控制器。

我不能添加更多的论据来证明这种做法是正确的,但它确实更加清晰。