@RestController和@Component之间的区别

时间:2019-10-13 20:44:12

标签: java spring spring-boot annotations spring-annotations

尽管互联网上的每个页面都说@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。

4 个答案:

答案 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。有关更多信息,请参见:DispatcherServletUpdated Doc Spring 5.x HandlerMapping < / p>

注意: 在较早版本的spring中,RequestMappingHandlerMapping会在spring之前启用。

总而言之:

  • DefaultAnnotationHandlerMapping是任何Spring托管组件的通用构造型 或豆。
  • @Component是持久层的构造型。
  • @Repository是服务层的构造型。
  • @Service是表示层(spring-MVC)的构造型。

Spring [Doc][4]

  

@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