首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >自定义注解实现springMVC的调用

自定义注解实现springMVC的调用

作者头像
分享干货的你
发布2021-04-06 16:33:38
发布2021-04-06 16:33:38
7930
举报
文章被收录于专栏:分享干货的你分享干货的你

1, 首先我们都清楚一个接口的调用,

  • 一个请求匹配前端控制器 DispatcherServlet 的请求映射路径(在 web.xml中指定), WEB 容器将该请求转交给 DispatcherServlet 处理
  • DispatcherServlet 接收到请求后, 将根据 请求信息 交给 处理器映射器 (HandlerMapping)
  • HandlerMapping 根据用户的url请求 查找匹配该url的 Handler,并返回一个执行链
  • DispatcherServlet 再请求 处理器适配器(HandlerAdapter) 调用相应的 Handler 进行处理并返回 ModelAndView 给 DispatcherServlet
  • DispatcherServlet 将 ModelAndView 请求 ViewReslover(视图解析器)解析,返回具体 View
  • DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)
  • DispatcherServlet 将页面响应给用户

也就是说真正的匹配的还是handlerMapping, 这里我们主要看handlermapping 的抽象类,并且实现它的方法。 就能做自定义的handlerMapping。

2, 我们看一下源码,当存在Controller注解或者requestmapping 注解的时候,然后在根据方法和处理器类型来找到RequestMappingInfo

我们点击进去看一下controller 和requestmapping的注解源码

这里我们发现 @Controller 和@Component 是别名,他俩是是一样的。

@RequestMapping 的注解 value 和path 是一样的。

这里@Controller 上面是加入bean 容器里面。

这里我们仿写一下。

代码语言:javascript
复制
@Component
@Retention(RetentionPolicy.RUNTIME) // 运行的时候生效。
@Target(ElementType.TYPE) // 声明标注再类上面。
public @interface CustomController {
}
代码语言:javascript
复制
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomMapping {
    // 请求URL
    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};
    // 请求的方法
    RequestMethod[] method() default {};
}
代码语言:javascript
复制
public class CustomRequestHandlerMapping extends RequestMappingHandlerMapping {

    @Override
    protected boolean isHandler(Class<?> beanType) {
       // 类上面有自定义的注解,才执行下面的。
        return AnnotatedElementUtils.hasAnnotation(beanType, CustomController.class);
    }

    @Override
    public void afterPropertiesSet() {
        // 第一优先级
        super.setOrder(0);
        super.afterPropertiesSet();
    }

    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
        RequestMappingInfo requestMappingInfo = createRequestMappingInfo(method) ;
        return requestMappingInfo ;
    }

    private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
        // 构造requestMappingInfo 
        CustomMapping customMapping = AnnotatedElementUtils.findMergedAnnotation(element, CustomMapping.class);
        return (customMapping != null ? builderMapping(customMapping) : null);
    }

    private RequestMappingInfo builderMapping(CustomMapping customMapping) {
        RequestMappingInfo.Builder builder = RequestMappingInfo
                .paths(customMapping.value())
                .methods(customMapping.method())
                .params(new String[] {})
                .headers(new String[] {})
                .consumes(new String[] {})
                .produces(new String[] {})
                .mappingName("") ;
        return builder.build() ;
    }

}

在把其加入spring容器了

代码语言:javascript
复制
@Configuration
public class CustomConfig {

    @Bean
    public CustomRequestHandlerMapping getRequestHandlerMapping(){
        return  new CustomRequestHandlerMapping();
    }
}

测试

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 分享干货的你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档