没错-有两个不同的应用程序上下文,由ContextLoaderListener加载的根应用程序上下文(在ServletContext初始化时)和Web上下文(由DispatcherServlet加载),根应用程序上下文是Web的父级上下文。
现在,由于这是两个不同的应用程序上下文,因此它们的作用方式有所不同-如果你
component-scan在应用程序上下文中定义服务,则将在此处创建服务的所有bean。
当你的Dispatcher Servlet加载时,它将开始创建Web上下文,在某个时候(由
<mvc:annotation-driven/>它驱动将为你的uri到处理程序方法创建映射,它将获取应用程序上下文中的bean列表(将是Web应用程序)上下文,而不是Root应用程序上下文),并且由于尚未在component-scan此处定义,因此将找不到与控制器相关的Bean,也不会创建映射,这就是为什么必须在调度程序Servlet上下文中定义组件扫描的原因也。
一个好的做法是在“根应用程序上下文”中排除与Controller相关的bean:
<context:component-scan base-package="package"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/></context:component-scan>
在Web应用程序上下文中,只有与控制器相关的一个:
<context:component-scan base-package="package" use-default-filters="false"> <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation" /></context:component-scan>



