0


@RestController 源码解读:解决 Web 开发中 REST 服务的疑难杂症

一、@RestContrller注解

1.1 查看底层源码

首先编写如下内容:

@RestController
public class TestController {

    
}

按住 Ctrl , 鼠标点击 @RestController 进入源码:

  1. @Target注解说明:查看底层源码发现
  2. @Documented:标明这个注解会包含在JavaDoc文档中
  3. @Retention:表示这个注解在运行时仍然有效,可以通过反射机制读取。

1.2 @AliasFor注解说明

@AliasFor是Spring框架的一个注解,用于声明注解属性的别名。它有两种不同的应用场景。

  • 注解内的别名
  • 元数据的别名

1.2.1 注解别名

查看@AliasFor注解源码:

通过该注解可以知道@AliasFor(value="xxx")和@AliasFor(attribute="xxx")的作用是相同的,接下来我们举例说明:

  1. 首先我需要自定义一个注解@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)public @interface MyInterface1 { String value1() default "";}当我们使用到该注解如 @MyInterface1(value1="number1"),表示 value1 的属性传入了 number1的值。现在如果自定义的注解改变为如下方式,但我希望通过 @MyInterface1(value2="number1") 达到上述相同的效果:@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)public @interface MyInterface1 { String value1() default ""; String value2() default "";}就可以添加@Alias()注解为注解内方法(因为@Alias作用域是方法注解)起别名:@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)public @interface MyInterface1 { @AliasFor(value = "value2") String value1() default ""; @AliasFor(value = "value1") String value2() default "";}达到 @MyInterface1(value2="number1") 和 @MyInterface1(value1="number1") 的效果相同。

注意事项:

  1. 组成别名对的每个属性都必须加上注释 @AliasFor,attribute()或value() 属性必须引用该对中另一个属性
  2. 别名属性必须声明相同的返回类型
  3. 别名属性必须声明一个默认值
  4. 别名属性必须声明相同的默认值

1.2.2 元数据别名

  1. 自定义第一个注解:@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)public @interface MyInterface1 { String value() default "";}

  2. 自定义第二个注解:@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)@MyInterface1public @interface MyInterface2 { @AliasFor(annotation = MyInterface1.class,value = "value") String value() default "";}此时@MyInterface1 (“number”)就和@MyInterface2(“number”)等价。这里可以理解成,注解MyInterface2的value属性重写了注解MyInterface1的value属性,但重新的属性的返回类型必须相同。此时再来查看@RestController 的@Alias:

     @RestController(value="xxxx")和@Controller(value="xxx")等价。
    

类似的使用包括:

可以看出对于value这个属性来说,@Configuration注解中的值会重写@Component的value属性值,这有点像类之间的继承,子类可以重父类的方法。我们也可以将@Configuration注解看成@Component的子注解


1.3 value() 方法的作用

@RestController

的定义中,

value()

方法使用

@AliasFor

注解将其与

@Controller

value

属性关联起来。这意味着当在

@RestController

上使用

value

属性时,它实际上等同于在

@Controller

上使用

value

属性,用于指定控制器的基本路径等相关信息,例如

@RestController("myControllerPath")

这种用法

也就是说

value

属性用于指定控制器的基本路径,那么我们进行接下来的测试:

  1. 首先编写Controller类代码:运行项目@RestController(value = "user")public class TestController { @RequestMapping("/test") public String test(){ return "测试成功!"; } }结果程序并没有识别到,发生404错误:

  2. 接下来测试/test路径:发现可以访问成功

  3. 所以如果是要填写路径的话,还是需要使用 @RequestMapping("/user/test")才是正确的,代码修改后测试: @RestController(value = "user")@RequestMapping("/user")public class TestController { @RequestMapping("/test") public String test(){ return "测试成功!"; }}此时就可以访问成功了:

  4. 一般情况下,我们修改为如下的规范:@RestController@RequestMapping("/user")public class TestController { @RequestMapping("/test") public String test(){ return "测试成功!"; }}

     所以value()方法的解释仅仅是 “建议”。
    

JDK 17 引入 records 新特性

标签: spring

本文转载自: https://blog.csdn.net/m0_75022408/article/details/143671631
版权归原作者 敖云岚 所有, 如有侵权,请联系我们删除。

“@RestController 源码解读:解决 Web 开发中 REST 服务的疑难杂症”的评论:

还没有评论