我已经有一段时间想知道这件事了,但我们还没有找到关于这个主题的任何内容。
让我们说我正在使用Spring MVC并定义一系列Controller
s。
@RestController
public abstract class AbstractController {
@Resource
private Environment env;
...
...
}
对于以下内容,@RestController
注册所需的UserController
注释是什么?
@RequestMapping(value = "/user")
public class UserController extends AbstractController {
@RequestMapping("value = "", method = RequestMethod.GET)
public ResponseEntity<User> getUser() {
...
return new ResponseEntity<>(user, HttpStatus.OK);
}
}
答案 0 :(得分:3)
如果您确定注释为@Inherited
,则为是。在此示例中,@RestController
未使用@Inherited
元注释定义,因此它不适用于AbstractController
的子类别。
答案 1 :(得分:1)
这里有两个问题。 SJuan76 has answered the first,关于类型注释的继承。
第二个问题
是
@RestController
注册所需的UserController
注释吗?
有点参与其中。
Spring有meta-annotations的概念:
Spring提供的许多注释都可以用作 您自己的代码中的元注释。元注释只是一个 可以应用于另一个注释的注释。
[...]
也可以组合元注释来创建组合注释。 例如,Spring MVC的
@RestController
注释是 由@Controller
和@ResponseBody
组成。
但是,组件扫描过程不会为abstract
类生成bean定义。更重要的是,它不会发现这些自身没有注释的子类型的元注释。换句话说,Spring将跳过UserController
类型,并且不会为它注册bean定义。 (我确信它可以,它只是4.1.7.RELEASE
的。)
现在,如果您使用UserController
注释类型@Component
以强制Spring生成bean定义,则处理@ResponseBody
的Spring MVC进程将检测@RestController
AbstractController
超类型上的注释。
这是在RequestResponseBodyMethodProcessor
中完成的,AnnotationUtils.findAnnotation
使用HttpEntityMethodProcessor
查找包含处理程序方法的类型的注释。它的javadoc陈述
在提供的
Annotation
上找到annotationType
的{{1}}个{} 遍历其界面,注释和超类如果 注释不存在于给定的类本身上。此方法显式处理不是的类级别注释 声明为继承的以及元注释和注释 接口
因此,如果你有
Class
Spring会检测并生成@Component
@RequestMapping(value = "/user")
public class UserController extends AbstractController {
的bean。使用UserController
处理程序方法处理对/user
的请求时,Spring MVC的运行方式就好像您的类实际上使用getUser
(或@RestController
)进行了注释。
但是,在您的情况下,您的处理程序方法再次返回@ResponseBody
。这不是由ResponseEntity
HandlerMethodReturnValueHandler
处理的,而是由available on GitHub here处理。
@ResponseBody
类的谨慎提示意味着是abstract
类型的超类型:如果您有许多子类型也意味着是bean而@Controller
超类型包含abstract
注释方法,Spring MVC将无法注册您的处理程序方法,因为它会考虑在它们之间复制超类型方法。