接下来我们通过@Controller 与 @RestController 的源码来瞧瞧它们之间的区别,我们先来看看@Controller的源码。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";
}
通过@Controller源码看出,它继承了@Component,这解释了@Controller定义类可以直接被Spring加载和实例化。
接下来我们来看看@RestController的定义。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
* @since 4.0.1
*/
String value() default "";
}
通过上面的代码可以看出@RestController是一个复合annotation,主要是包含了@Controller和@ResponseBody。
也就是说@Controller 和 @RestController的区别就是 @ResponseBody,那么我们来看看@ResponseBody又是用来干嘛的?
Annotation that indicates a method return value should be bound to the web response body. Supported for annotated handler methods in Servlet environments.
也就是说@ResponseBody 会将方法返回值塞到请求的 response body里,那在实际情况下会带来什么问题呢?
由于@ResponseBody会把方法返回值直接塞到请求的 response body里,导致如果某个方法需要做页面跳转(比如,跳转到 html. jsp, ftl),是没办法成功的。