注释是否适用于子类?

时间:2015-10-28 23:33:39

标签: java spring-mvc inheritance annotations

我已经有一段时间想知道这件事了,但我们还没有找到关于这个主题的任何内容。

让我们说我正在使用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);
    }          
}

2 个答案:

答案 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将无法注册您的处理程序方法,因为它会考虑在它们之间复制超类型方法。