Java - Spring MVC 中的 @RequestMapping
是什么技术(原理 or 语法)?
注:本人对 Java 不太熟,看到这个就想了解清楚一点,也作为一种学习的切入点吧。
Example:
@RestController
public class IndexController{
// ...codes....
@RequestMapping("/url_path/")
public String the_function(){
return "access /url_path/";
}
}
问题:
@RequestMapping
是什么技术(原理 or 语法)?
类比 Python 的话,是等效于 Python 中的装饰器吗?
还是说 Java 的在函数上写 @xxx()
是另外一种完全不同的原理(语法)
这里说的“语法不同”就类似于 ‘装饰器’ 和 ‘切片’ 和 ‘生成器’ 这种意义上的不同。
这个是注解,但 Java 中的注解本身并不提供任何功能,它只是作为一种标记,需要额外的代码去处理它.
无论是编译期还是运行期,通过反射能拿到注解的代理实例,或者说注解的本质是一个接口(JDK 提供的代理
Proxy
只能代理接口). 你在注解里声明的所有属性都会作为接口上的方法由这个代理实例去托管. 这些方法去代理实例托管的一个Map
里去这个代理实例里取值(同一个注解在不同代码位置上使用会产生不同的代理实例,每个代理实例维护一个Map
用以保存各自的值).如果是编译期的注解,想处理就需要编写注解处理器(Annotation Processor),这个可以做到代码生成(lombok 等等)或一些其他基于源码的增强(也包括 AST 级别的代码检测);
如果是运行期的注解,想处理就有很多方式,比如最简单得,直接通过反射访问一个对象实例身上的注解;或是通过切面将注解视为一种标记点.
注解如果单纯视为标记的话其实跟接口从语义上来说的确没有太大区别. 但它的主要语义是『元信息』.
最后,
@RequestMapping
的原理,并不是所谓的切面实现. Spring 启动过程中会注入所有的@Component
及相关注解,这是通过包扫描得到的,这些类会被 Spring 进行托管,在处理的过程中会有个初始化处理器、或类身上通过接口获得的 Bean 生命周期方法、或工厂用来对刚建立的对象实例进行增强(比如用代理包起来),其中@Controller
、@RestController
这两个注解标记的类会在RequestMappingHandlerMapping
里被搜集出来,进一步提取里面的公开非静态方法,如果方法上有@RequestMapping
则称之为HandlerMethod
,然后有其他的步骤用来计算方法与路由的映射关系,最后汇总.