我一直在研究使用 mvc:annotation-driven 标签时我们有什么额外的功能,我很难消化结果,尤其是在@Controller注释方面。 我知道这与这个问题非常相似,但请听我说。
根据春季文档
@Controller注解的基本目的是充当批注类的构造型,指示其角色。调度程序将扫描此类带注释的类以查找映射的方法,检测@RequestMapping注释(请参阅下一节(。
然后,文档继续显示上下文:组件扫描标记提供了这种支持。 所以这一切都很好,但是后来我正在研究mvc:annotation-drive给我们的东西,前面提到的stackoverflow问题提供了以下答案。
MVC:Annotation-driven 声明了对注释驱动的 MVC 控制器的显式支持(即 @RequestMapping、@Controller,尽管对这些控制器的支持是默认行为(,并通过 @Valid 添加对 declrative 验证的支持,并使用 @RequestBody/ResponseBody 进行消息正文封送。
这对我来说似乎有点多余。 也许我不明白这种明确的支持是什么。 再次,回到官方的Spring文档,我们得到以下内容
[mvc:annotation-driven] 注册 Spring MVC 向@Controllers调度请求所需的 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter bean。
这听起来与我从文档中提供的最后一个示例非常相似。如果有人可以提供一些示例,说明我们可以仅使用 context:component-scan 标签来处理@Controller注释,有哪些限制,然后添加 mvc:annotation-driven 标签时我们得到的附加功能,我认为这将非常有帮助。 提前感谢您对此的任何支持。
这两个元素都有完全不同的目的。
顾名思义,<context:component-scan />
用于组件扫描。默认情况下,它会扫描所有带有@Component
注释的 bean(或"子"注释,如 @Controller
、@Service
等(。它只会在应用程序上下文中将这些类的实例注册为 bean。仅此而已。
<mvc:annotation-driven />
用于引导Spring MVC,它注册了RequestMappingHandlerMapping
和RequestMappingHandlerAdapter
。第一个将请求链接到某个方法(@Controller
注释类中方法的@RequestMapping
注释(。最后一个知道如何执行用@RequestMaping
注释的方法。
现在,<mvc:annotation-driven />
不会扫描或检测@Controllers
如果应用程序上下文中没有请求映射,则不会进行请求映射。现在,您有几种方法可以在应用程序上下文中注册这些 bean,其中之一是上述<context:component-scan />
。
基本上,没有<mvc:annotation-driven />
的@Controller
是毫无用处的,因为它除了占用内存之外什么都不做。它不会绑定到传入的请求,它只是在应用程序上下文中徘徊。它只是另一种豆子,就像所有其他豆子一样,对它没有任何特别的处理。(最近但已弃用的 Spring 版本注册了处理@Controller
的DefaultAnnotationHandlerMapping
,但这已被弃用(。
context:component-scan
元素列出了一个软件包,Spring 应该扫描该软件包以查找@Controller注释(在 base-package
属性中(。
mvc:annotation-driven
没有这样的属性。 这是一个方便的元素,它将大量默认 MVC 元素安装到应用程序上下文中。 这些元素列在 Spring 框架参考的第 16.14.1 节中。 此元素似乎不会扫描@Controller批注。
与普遍的看法相反,这些因素之间没有依赖关系。 没有mvc:annotation-driven
的@Controller将毫无问题地运行,并且可以很好地处理HTTP请求,只要您包含具有适当base-package
属性的context:component-scan
即可。
-
案例1(注释驱动(
这是启用 Spring 注释标签。所有注释,例如
@Controller, @Service, @Autowired
等。可以使用。这不会创建一个 bean,而是找到注释,如果找到注释(例如@Controller, @Service, @Autowired
等(,Spring 会为该类创建相应的 bean。 -
案例2(组件扫描(
Spring 将扫描声明中指定的类的包(和子包(,并为其创建 bean。