欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot之@Controller和@RequestMapping的實現(xiàn)原理解讀

 更新時間:2025年04月19日 09:26:58   作者:西魏陶淵明  
這篇文章主要介紹了SpringBoot之@Controller和@RequestMapping的實現(xiàn)原理,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

SpringBoot之@Controller和@RequestMapping的實現(xiàn)原理

干貨分享,SpringBoot中Web接口資源是如何被管理起來呢?

一個請求,通過在瀏覽器上輸入了一個url,是如何被SpringWeb匹配到對應的方法的呢?

帶著這個疑問我們來學習本篇。

瀏覽器的請求,是如何被映射到后端服務的方法上呢?

后端服務使用SpringBoot只使用了一個注解就提供了web服務的實現(xiàn)原理是什么呢?

@RestController
public class TestController {

    @GetMapping("/name")
    public String name(HttpServletRequest request){
        return request.toString();
    }
}

帶著上面的疑問,小編通過源碼的方式帶你一看究竟吧。 為了能讓各位童鞋更好的更容易的理解。第一趴我們先來補充點知識點。

一、注解派生概念

在java體系中,類是可以被繼承,接口可以被實現(xiàn)。但是注解沒有這些概念,而是有一個派生的概念。舉例,注解A。被標記了在注解B頭上,那么我們可以說注解B就是注解A的派生。

下面我們舉一個例子:

@RestController
public class PostController {

    @ApiOperation(value = "查詢Bbs所有文章")
    @PostMapping(value = "/query/bbs/posts", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<PostAllResponse> queryBbsPostAll(@RequestBody PostAllSelectRequest postAllSelectRequest) {
        return postBiz.queryBbsPostAll(postAllSelectRequest);
    }

    public static void main(String[] args) {
        Method queryBbsPostAll = ClassUtils.getMethod(PostController.class, "queryBbsPostAll",PostAllSelectRequest.class);
        PostMapping annotation = AnnotationUtils.findAnnotation(queryBbsPostAll, PostMapping.class);
        ///query/bbs/posts
        System.out.println(StringUtils.arrayToCommaDelimitedString(annotation.value()));
        //application/json
        System.out.println(StringUtils.arrayToCommaDelimitedString(annotation.produces()));
        //是否包含RequestMapping: true
        System.out.println("是否包含RequestMapping: "+AnnotatedElementUtils.hasAnnotation(queryBbsPostAll,RequestMapping.class));

        RequestMapping mergedAnnotation = AnnotatedElementUtils.getMergedAnnotation(queryBbsPostAll, RequestMapping.class);
        ///query/bbs/posts
        System.out.println(StringUtils.arrayToCommaDelimitedString(mergedAnnotation.value()));
    }
}
  • queryBbsPostAll是用了PostMapping類進行標記是一個POST資源
  • 我們通過main方法里面可以知道。通過反射我們能拿到Method上的PostMapping注解信息。
  • 但是看這一行AnnotatedElementUtils.hasAnnotation(queryBbsPostAll,RequestMapping.class)為什么也是true呢?

沒錯因為PostMapping是RequestMapping的派生注解。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.POST)
public @interface PostMapping {
   ...
}

請記住這個小的知識點,后面的邏輯會用到。因為下面后有大量的源碼,為了方便標注,小編使用截圖的形式,在截圖上會加上注釋信息。 ?

二、進入正題,跟進源碼解析請求Method

通過跟進源碼,我們會發(fā)現(xiàn)這樣一個類。AbstractHandlerMethodMapping。其實現(xiàn)了實現(xiàn) InitializingBean接口。在當前 Bean初始化時候會執(zhí)行afterPropertiesSet -> initHandlerMethods。

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        initHandlerMethods();
    }
    
    /**
  * Scan beans in the ApplicationContext, detect and register handler methods.
  * @see #getCandidateBeanNames()
  * @see #processCandidateBean
  * @see #handlerMethodsInitialized
  */
    protected void initHandlerMethods() {
        for (String beanName : getCandidateBeanNames()) {
            if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                processCandidateBean(beanName);
            }
        }
        handlerMethodsInitialized(getHandlerMethods());
    }
}

RequestMappingHandlerMapping解析Method上的RequestMapping信息

isHandler 方法判斷是否是web資源類。當一個類被標記了 @Controller 或者@RequestMapping。 注意 @RestController 是@Controller的派生類。所以這里只用判斷 @Controller 或者@RequestMapping就行了。

 @Override
 protected boolean isHandler(Class<?> beanType) {
  return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
    AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
 }

detectHandlerMethods方法就是真正開始解析Method的邏輯。通過解析Method上的 @RequestMapping或者其他派生的注解。生成請求信息。 注意這個請求信息里面也是有很多邏輯的不過不是本篇討論的重點,就不說了。稍微提一下。根據(jù)規(guī)則來匹配url邏輯就在這里面。

這里我們能看到源碼里拿到了Method并拿到了執(zhí)行這個Method的實例Bean。在這里封裝成了HandlerMethod并注冊到了MappingRegistry中。

在注冊的過程中把RequestMapping中的路徑信息同事也放到一個urlLookup中。key是url,value是Mapping信息。

到這里其實我們就把本篇的議題就說明清楚了。下面我們在看下SpringWeb是如何將http請求信息路由到具體的HandlerMethod的吧。

三、最后串一下請求流程

看了前面的截圖,我們知道Spring是如何把這些Web資源信息給保存起來的了。然后就看是DispatcherServlet的邏輯了。 首先DispatcherServlet 是一個Servlet。Servlet相信大家都都知道就不重點說原理。 我們直接看doService -> doDispatch 方法

根據(jù)請求路徑,找到從Mapping信息,然后根據(jù)Mapping信息匹配到具體的HandlerMethod。 ok本篇內(nèi)容就到這里。謝謝大家。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Maven繼承父工程時的relativePath標簽解析用法小結(jié)

    Maven繼承父工程時的relativePath標簽解析用法小結(jié)

    relativePath 的作用是為了找到父級工程的pom.xml,本文主要介紹了Maven繼承父工程時的relativePath標簽解析用法小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • 詳解Java集合類之HashSet篇

    詳解Java集合類之HashSet篇

    這篇文章主要為大家詳細介紹一下Java集合類中HashSet的用法,文中的示例代碼講解詳細,對我們學習Java有一定幫助,感興趣的可以了解一下
    2022-07-07
  • Kotlin null的處理詳解

    Kotlin null的處理詳解

    這篇文章主要介紹了Kotlin null的處理詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • java利用udp實現(xiàn)發(fā)送數(shù)據(jù)

    java利用udp實現(xiàn)發(fā)送數(shù)據(jù)

    這篇文章主要為大家詳細介紹了java利用udp實現(xiàn)發(fā)送數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Java數(shù)據(jù)導入功能之讀取Excel文件實例

    Java數(shù)據(jù)導入功能之讀取Excel文件實例

    這篇文章主要介紹了Java數(shù)據(jù)導入功能之讀取Excel文件實例,本文給出了jar包的下載地址以及讀取Excel文件的代碼實例,需要的朋友可以參考下
    2015-06-06
  • 超細講解Java調(diào)用python文件的幾種方式

    超細講解Java調(diào)用python文件的幾種方式

    有時候我們在寫java的時候需要調(diào)用python文件,下面這篇文章主要給大家介紹了關于Java調(diào)用python文件的幾種方式,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • Java 中的語法糖,真甜

    Java 中的語法糖,真甜

    語法糖(Syntactic sugar),也叫做糖衣語法,是英國科學家發(fā)明的一個術語,通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機會.這篇文章主要介紹了Java 中的語法糖知識,需要的朋友可以參考下
    2020-12-12
  • mybatis3使用@Select等注解實現(xiàn)增刪改查操作

    mybatis3使用@Select等注解實現(xiàn)增刪改查操作

    這篇文章主要介紹了mybatis3使用@Select等注解實現(xiàn)增刪改查操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java解析調(diào)用webservice服務的返回XML串詳解

    Java解析調(diào)用webservice服務的返回XML串詳解

    這篇文章主要介紹了Java解析調(diào)用webservice服務的返回XML串詳解的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • java面向?qū)ο笤O計原則之迪米特法則分析詳解

    java面向?qū)ο笤O計原則之迪米特法則分析詳解

    這篇文章主要為大家介紹了java面向?qū)ο笤O計原則之迪米特法則的示例分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,學有所得
    2021-10-10

最新評論