环境:Spring5.3.23
1. 简介
在Spring中要定义一个接口是非常的简单,如下示例:
@RestController
@RequestMapping("/demos")
public class DemoController {
@GetMapping("/index")
public Object index() {
return "index" ;
}
}
通过上面的@RestController, @RequestMapping就完成了一个简单的接口定义。
实际Spring Web底层是做了很多的工作,其核心组件有HandlerMapping, HandlerAdapter, ViewResolver等组件。
- HandlerMapping根据当前请求的URI,查找对应的Handler,如:HandlerExecutionChain,包装的HandlerMethod
- HandlerAdapter根据上面的确定的HandlerMethod, 找到能够处理该Handler的Adapter,进行调用
- ViewResolver如果返回的ModelAndView对象那么会通过相应的ViewResolver进行渲染输出
了解了上面的几个核心组件之后,接下来就是自定义实现上面的核心类,来完成接口的请求处理。
2. 实战案例
2.1 自定义Endpoint
自定义@PackEndpoint注解,该注解的功能就类似@Controller标记这个类是一个处理器类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PackEndpoint {}
参数注解,该注解的作用就类似@RequestParam
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PackParam {
}
2.2 参数封装对象
该类的作用用来保存方法的参数相关的信息进行封装,如:参数名称,参数的类型及对应的方法Method。
public class PackMethodParameter {
// 用来解析接口参数的名称
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer() ;
private String name ;
private Executable executable ;
private int parameterIndex ;
private Class type ;
public PackMethodParameter(String name, int parameterIndex, Executable executable) {
this.name = name;
this.parameterIndex = parameterIndex ;
this.executable = executable ;
}
public PackMethodParameter(int parameterIndex, Executable executable, Class type) {
this.parameterIndex = parameterIndex ;
this.executable = executable ;
this.type = type ;
}
public boolean hasParameterAnnotation(Class