2018年不知不觉已经走到了尾声,你还在为分不清@Controller和@Restcontroller而烦恼吗?这篇博文从源码层面分析这两个注解,值得一读。
首先贴一张源码的图,对比一下,左边是@Controller的源码,右边是@RestController的。

如果觉得不清楚,看下面代码:
@Controller:
View Code@RestController:
View Code显然,两个注解的源码里面都包含许多的注解:
@Controller的注解包括:@Target({ElementType.TYPE})、@Retention(RetentionPolicy.RUNTIME)、@Documented、@Component
@RestController的注解包括:@Target(ElementType.TYPE)、@Retention(RetentionPolicy.RUNTIME)、@Documented、@Controller、@ResponseBody
所以,源码的分析也就是对注解的分析。
内置注解和元注解
注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
Java SE5中有三种内置注解:
| @Override | 表示当前的方法定义将覆盖超类中的方法 |
| @Deprecated | 如果程序中使用了注解为它的元素,那么编译器会发出警告 |
| @SuppressWarnings | 关闭不当的编译器警告信息 |
元注解是专门负责注解其他的注解,Java内置了四种元注解,专门负责新注解的创建,直接看这张表格(摘自Java编程思想):
| @Target | 表示该注解可以用于什么地方。可能的ElementType参数包括: CONSTRUCTOR:构造器的声明 FIELD:域声明(包括enum实例) LOCAL_VARIABLE:局部变量声明 METHOD:方法声明 PACKAGE:包声明 PARAMETER:参数声明 TYPE:类、接口(包括注解类型)和enum声明 |
| @Retention | 表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括: SOURCE:注解将在编译器丢弃 CLASS:注解在class文件中可用,但会被VM丢弃 RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息 |
| @Documented | 将此注解包含在Javadoc中 |
| @Inherited | 允许子类继承父类中的注解 |
现在,明白了@Target({ElementType.TYPE})、@Retention(RetentionPolicy.RUNTIME)、@Documented的作用,我们也可以自定义一个注解@Algorithms:
/** * * Define a annotation named Algorithms * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Algorithms { String value() default ""; }
@Component注解
@Component注解源码如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Indexed public @interface Component { /** * 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 (or empty String otherwise) */ String value() default ""; }

