尽管互联网上的每个页面都说@RestController是@Component的规范。我不知道它是否必须与DispatcherServlet有关。但是当我通过在@RestController和@Component之间切换来尝试下面的代码时,我看不到相同的行为:
首先,我尝试使用@RestController:
@RestComponent
public class TestController {
@RequestMapping(value="/testController", method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE)
public void testController() {
System.out.println("Hello");
}
}
我在控制台中得到以下输出:
你好
第二,我尝试使用@Component + @ResponseBody:
@Component
@ResponseBody
public class TestController {
@RequestMapping(value="/testController", method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE)
public void testController() {
System.out.println("Hello");
}
}
邮递员出现错误:
{
"timestamp": 1570998345860,
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'POST' not supported",
"path": "/testController"
}
如果两个注释都相同,那么为什么输出会有所不同?
下面是@RestController和@Controller的源代码,它显示了@RestController和@Controller都是@Component的规范:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
}
也许它必须与DispatcherServlet有关。分派器Servlet可能仅在@RestController注释类中检查URL。
答案 0 :(得分:1)
仅仅因为@RestController
是@Component
并不意味着您可以通过切换到较宽的@Component
来实现相同的功能。即使添加了@ResponseBody
,您也无法实现等效的功能(不支持通过请求方法POST
表示)。
用@Component
替换@Controller
,因为@RestController
具有与@Controller
+ @ResponseBody
完全相同的功能。您还可以在@RestController
的元注释中看到此内容,并看到它用@Controller
进行元注释,而不仅仅是@Component
。反过来,@Controller
用@Component
进行元注释。
答案 1 :(得分:0)
您不应获得相同的行为,因为@Component更通用。它仅将您的类注册为Spring Managed Bean。但是,@ RestController不仅将您的类注册为托管Bean,还将其注册为对指定URL路径的HTTP调用的入口点。其他特定于图层的批注也是如此,例如@ Repository,@ Configuration e.t.c
答案 2 :(得分:0)
@Controller
,@RestController
,@Service
等都是使用@Component
注释进行元注释的注释。所有这些批注本质上都是@Component
批注针对特定用例的专业化。
@Component
批注通常用于注册Spring bean。
@Controller
批注即使在内部用@Component
批注,也提供了完全不同的功能。通过对带有此批注的类进行批注,我们实际上是在告诉Spring扫描此类{{1 }}注释,用于注册bean以进行请求映射。仅使用@RequestMapping
批注就不会发生这种情况。
spring应用程序启动时,@Component
将启用DispatcherServlet
RequestMappingHandlerMapping
(这是一个处理程序映射,用于在RequestMappingHandlerAdapter
上查找@RequestMapping
注释s)。因此,当请求到达调度程序servlet时,它会将其交给@Controller
,后者将uri解析为控制器方法bean。有关更多信息,请参见:DispatcherServlet
,Updated Doc Spring 5.x HandlerMapping
< / p>
注意:
在较早版本的spring中,RequestMappingHandlerMapping
会在spring之前启用。
总而言之:
DefaultAnnotationHandlerMapping
是任何Spring托管组件的通用构造型
或豆。@Component
是持久层的构造型。@Repository
是服务层的构造型。@Service
是表示层(spring-MVC)的构造型。
@Controller
批注指示特定的类服务 控制器的角色。
@Controller
批注的基本目的是充当 注释类的构造型,指示其作用。的 调度程序将扫描此类带注释的类以查找映射的方法, 检测@Controller
注释(请参阅下一节)。可以使用标准显式定义带注释的控制器bean。 调度程序上下文中的Spring bean定义。然而
@RequestMapping
原型也允许自动检测,与 Spring 2.5在检测组件类中的常规支持 它们的类路径和自动注册Bean定义。
相似的帖子:What's the difference between @Component, @Repository & @Service annotations in Spring?
答案 3 :(得分:0)
@Controller是传统控制器中的用户,并引入了@RestController注释以简化RESTful Web服务的创建。 这是一个方便注释,它结合了@Controller和@ResponseBody
@Controller注释只是@Component类的专用,并允许通过类路径扫描自动检测实现类。
@Controller通常与在请求处理方法上使用的@RequestMapping注释结合使用。
请求处理方法带有@ResponseBody注释。该批注允许将返回对象自动序列化为HttpResponse。
@RestController是控制器的专用版本。它包含@Controller和@ResponseBody批注,因此简化了控制器的实现。
控制器带有@RestController注释,因此不需要@ResponseBody。
控制器类的每个请求处理方法都会自动将返回对象序列化为HttpResponse。
详细信息请参见:https://www.baeldung.com/spring-controller-vs-restcontroller