我读过了:
Spring MVC 中的 ApplicationContext 和 WebApplicationContext 有什么区别?
如果 <context:component-scan /> 在应用程序上下文而不是调度程序上下文中,@RequestMapping 注释不起作用(稍后会详细介绍)
和其他几个,但这些都没有回答这个问题:
<context:component-scan.../>
当 Spring MVC 应用程序的 ROOT 上下文中存在时,为什么范围是有限的?
我的理解是,它会导致扫描指定包中的所有类,并实例化任何使用其原型@Component
或其任何子原型(@Repository
和@Service
)的 bean @Controller
。
鉴于:
applicationContext.xml(根上下文)
<beans...>
...
<context:component-scan base-package="com.myproject"/>
<context:property-placeholder
ignore-resource-not-found="true"
location="classpath:default.properties, file:///etc/gallery/gallery.properties"/>
</beans>
main-servlet.xml(servlet 上下文)
<beans ...>
...
<mvc:annotation-driven/>
<mvc:resources mapping="/image/**" location="file:/${gallery.location}" />
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/images/**" location="/images/"/>
...
</beans>
com/myproject/web/MainController.java
package com.myproject.web;
@Controller
public class MainController
{
...
@RequestMapping("/gallery/**")
public String gallery(ModelMap modelMap, HttpServletRequest req, HttpServletResponse resp) throws IOException
{
...
}
}
Spring 文档声明在根上下文中实例化的任何 bean 都是共享的,并且可用于各个 servlet 应用程序上下文。因此,根上下文中的两个<context:...>
声明应该导致在 servlet 上下文中可见的 bean。但情况似乎并非如此。我需要在 servlet 上下文中<context:component-scan.../>
重复。<context:property-placeholder.../>
在 servlet 上下文中省略 会<context:component-scan.../>
导致
Sep 15, 2015 10:08:16 AM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/gallery/habitat/20150813] in DispatcherServlet with name 'main'
Sep 15, 2015 10:08:16 AM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/error] in DispatcherServlet with name 'main'
表示@Controller
未解决。
使用未处理的属性引用省略注释中的<context:property-placeholder.../>
结果@Value
,在我的情况下会导致一些断开的链接。
由于这两个<context:.../>
指令都会导致 bean 实例化,我很困惑为什么 bean 在子上下文中不可见,这与文档直接矛盾。此外,没有两个component-scan
语句会导致控制器 bean 被实例化两次吗?
关于@RequestMapping 注释不起作用,如果 <context:component-scan /> 在应用程序上下文而不是调度程序上下文中,我确实<mvc:annotation-driven />
在我的应用程序上下文中,并且这里的答案没有解释为什么component-scan
需要两个语句。
除非我完全理解它是如何工作的并且可以预测当我调整某些东西时它会如何表现,否则我对使用“魔法”感到非常不舒服。所以“两个地方都加就继续”的“解决方案”是不能接受的。