개요
웹 개발자의 경우 MVC 모델은 모든 사람에게 매우 친숙합니다. SpringMVC에서 조건을 충족하는 요청은 요청 분배를 담당하는 Dispatcherservlet에 들어갑니다. DispatcherServlet은 요청 URL을 컨트롤러에 맵핑합니다 (핸드 리머핑에 저장). Handlermpapping은 마지막으로 특정 처리 객체 핸들러 (즉, 프로그램을 프로그래밍 할 때 쓴 내용)를 포함하는 HandlereXecutionChain을 반환합니다. 컨트롤러) 및 일련의 인터셉터. 현재 Dispatcherservlet은 반환 된 HandlerExecutionChain의 핸들러의 핸들러를 기반 으로이 프로세서 유형을 지원하는 핸들러 라디페를 찾을 수 있습니다. 프로세서 어댑터에서 결국 컨트롤러의 요청 응답 메소드를 호출하고 결과보기 (ModelAndView)를 반환합니다. 결과 뷰를 얻은 후 결과는 렌더 메소드를 통해 표시됩니다.
상속 시스템의 핸 드래핑 :
SpringMVC는 핸들러 프로세서에 배포를 요청합니다. 이 단계는 핸드 레이핑 모듈을 통해 해결됩니다. 핸드 램핑은 또한 인터셉터를 처리합니다.
먼저 핸드 lermapping의 상속 트리를 살펴 보겠습니다.
다음과 같이 분류 할 수 있습니다.
1. 인터페이스 핸드 링핑, API 정의 : handlerexecutionchain gethandler (httpservletrequest 요청)는 예외를 던집니다.
2. 기본 초록 클래스 : 주로 컨텍스트 환경을 준비하고 Gethandlerinternal Hook를 제공하고, 인터셉터를 HandlerExecutionChain에 캡슐화합니다.
3. @Controller 사용, 주석을 기반으로 @RequestMapping
4. 구성 파일의 URL에서 핸들러로 간단한 handlermapping을 구성합니다.
5. BeannameurlHandlerMpapping은 기본적으로 구현됩니다
6. 컨트롤러 서브 클래스의 매핑
핸드 램핑을 살펴 보겠습니다. Gethandler API 만 매우 간단합니다.
// HandlermappingPackage org.springframework.web.servlet; public interface handlermpapping {Handlerexecutionchain gethandler (httpservletrequest 요청) 예외가 발생합니다;} AbstracthandLermpapping은 그렇게 간단하지 않습니다
먼저 ABSTRACTHANDLERMAPPING 및 구현 된 인터페이스가 상속받은 클래스를보십시오.
패키지 org.springframework.web.servlet.handler; public Abstract Class AbstracthandLermpapping webApplicationObjectSupportimplements 핸드 lermping, 주문 {// ...}. WebApplicationObjectSupport는 컨텍스트 ApplicationContext 및 ServletContext를 제공하는 데 사용됩니다.
여기에는 InitApplicationContext 메소드가 있으며, 이는 향후 종종 사용됩니다. ABSTRACTHANDLERMAPPING은 직접 재정의됩니다.
ApplicationContextAware 및 ServletContextAware 인터페이스는 여전히 상위 클래스에서 구현되며 스프링 개념은 매우 통합되어 있습니다.
순서는 수집 분류에 사용됩니다.
AbstracthandLermping의 속성을 계속 살펴 보겠습니다
// ABSTRACTHANDLERMAPPING // 순서는 최대 값을 할당하며 우선 순위는 가장 작은 개인 int order = integer.max_value입니다. // default : nonordered handler와 동일 // 여기에 사용 된 OBEJCT 및 서브 클래스 구현, 핸드머 메드, 핸드 레스 컨테 션 체인 및 기타 개인 객체 DefaulThandler; // url 계산에 대한 보조 클래스를 사용하여 urlpathhelper urlpathelper = new urlpathelper (new urlpathelper); // Pathmather를 기반으로하는 urlpathhelper urlpathelper = new urlpathelper (// Pathmatch)를 기반으로합니다. AntpathMatcher (); // 인터셉터 구성 :, 핸드 레이저 핑 속성 설정;, ExtendInterceptors Set Private Final List <Bebject> 인터셉터 = New ArrayList <botorceptor = // 인터셉터에서 구문 분석하고 모든 핸들러 프라이버시 목록에 직접 추가하여 <brongernorceptor> 어댑티브리스트 <handlerlist <brongerceptor> (); 일치가 전달되면 개인 최종 목록 <MapPapedInterceptor> MappedInterceptor = new ArrayList <MapPedinterceptor> ();
인터셉터의 초기화를 확인하십시오.
// obstracthAndLermpapping@attremprotected void initApplicationContext ()는 beansexception {extendInterceptors (this.interceptors); initinterceptors ();}/***가 서브 클래스 확장 인터셉터에 제공되지만 불행히도 사용되지 않음*/protected extendectors (). {}/*** 애플리케이션 아래의 매핑 인터셉터를 스캔하여 매핑 된 인터셉터*/보호 된 void detectMappedInterceptors (list <mapappedinterceptor> mappedinterceptors) {mappedinterceptor.addall (beanfactoryUtil.beansoftypeinText (getApplicationContext (), mapped Interceptor.clecector.cleceptor.cleceptor. false) .values ());}/*** 핸들러 인터셉터 및 webrequestinterceptor*/protected void initinterceptors () {if (! this.interceptor.isempty ()) {for (int i =; i <this.interceptors.size (); i ++)에 적응합니다. NULL) {NEW NEW IRMERGALARGUMENTEXCEPTION (인터셉터 배열의 "입력 번호" + I + "는 NULL입니다. Adaptinterceptor (객체 인터셉터) {if (interceptor instanceof handlerinterceptor) {return (handlerinterceptor) interceptor;} else if (webRequestinterceptor의 interceptor instance) {return new webRequestHandlerinterceptoradapter (webRequestInterceptor) interceptor (webRequestinterceptor) interceptor); interceptor.getClass (). getName ());}}그런 다음 Gethandler (httpservletrequest 요청)의 구현이 있으며, 여기에서는 서브 클래스 구현을위한 Gethandlerinternal (httpservletrequest 요청)도 보유합니다.
// ABSTRACTHANDLERMAPPINGPUBLIC 최종 HandLEREXECUTECUTECHAIN GETHANDLER (httpServletRequest 요청) 예외를 {객체 handler = gethandlerInternal (request); if (handler == null) {handler = getDefaulthandler ();} if (handler == null) {reter null 또는 eNull 또는 if if if if if if if if (handled). String) {String handlername = (String) handler; handler = getApplicationContext (). getBean (handlername);} return gethandlerexecutionchain (handler, request);} 보호 된 추상 개체 gethandlerinternal (httpservletrequest 요청) 예외; 마지막으로, 인터셉터를 핸드 레크 컨디션 체인으로 캡슐화하십시오
적응 된 인터셉터를 직접 추가하십시오
URL에 따라 매핑 된 후 매핑 된 인터셉터를 추가해야합니다.
// ABSTRACTHANDLERMAPPINGPROTECTED HARDLEREXECUTECUTECHAIN GETHANDLEREXECUTECUTECHAIN (객체 핸들러, httpservletRequest 요청) {HandlerExecutionChain Chain = (handler instanceof handlerexecutionChain) handler : New HandleRexecutionChain (handler); chain.addinterceptors (getAdAptedInterceptors ()); 문자열 lookuppath = urlpathHelper.getLookUpPathForquest (요청); for (MappedInterceptor MappedInterceptor : MappedInterceptors) {if (MappedInterceptor.matches (LookupPath, Pathmatcher)) {chain.AddGintercepor.GetInterceptor (interceptor) 체인;} 컨트롤러 서브 클래스의 매핑은 먼저 클래스 상속을 살펴 봅니다.
각 카테고리의 주요 책임에 대해 이야기 해 봅시다.
1. ABSTRACTHANDLERMAPP 컨텍스트 환경을 준비합니다. gethandlerinternal hook를 제공합니다. 인터셉터를 핸드 레크 컨디션 체인으로 캡슐화하십시오
2. AbstractUrlHandlerMpapping은 서브 클래스 사용을 위해 핸들러를 등록하는 방법을 구현합니다. gethandlerinternal을 구현하고 서브 클래스로 초기화 된 구성 정보를 기반으로 핸들러를 찾습니다.
3. AbstractDetectingUrlHandlerMpapp 응용 프로그램에서 객체를 스캔하고 반복 후 후크 방법을 제공하여 필터링 방법을 결정합니다.
4. AbstractControllerUrlHandlerMpapping implements goundsForHandler, 핸들러 작동 (구성 파일 구성)을 추가하고 서브 클래스 구현을위한 Hook 메소드 BuildUrlSforHandler를 보유합니다. 동시에 컨트롤러의 서브 클래스를 판단합니다
5. ControllerBeanNameHandlerMpapping Bean 이름을 기반으로 URL을 생성합니다
ControllerClassNameHandLermpapping 클래스 이름을 기반으로 URL을 생성합니다
AbstractUrlHandlerMpapping부터 시작하겠습니다. 여기서 우리는 단지 코드를 대략 살펴 봅니다. 신중하게 분석 해야하는 경우 <SpringMVC 소스 코드 해석 - 핸드 레이핑 - AbstractUrlHandlerMpapping Series 요청 배포로 이동하십시오.
핸들러 등록
Protected Void RegisterAndler (String [] urlpaths, String beaname)은 Beansexception, 불법 상태 {} 보호 된 void register hanghandler (문자열 URLPATH, 객체 핸들러)를 a Beansexception, 불법 스테이트 렉션 {} 던지기 핸들러 검색
보호 된 객체 gethandlerinternal (httpservletrequest 요청)은 예외 {} // handlerprotected 객체 kookuphondler (String urlpath, httpservletrequest 요청) 예외 {} // handlerprotected void validater (object handler, httpertrequest rectrows)를 검증합니다. handlerexecutionchainprotected 객체 buildPathExpositingHandler (개체 RawHandler, String BestMatchingPattern, String thatwithInMapping, Map <String, String> uritemplateVariables) {}AbstractDetectingUrlHandlerMpapping, 이것은 확장되지 않았다. 자세히 이동하십시오 <springmvc 소스 코드 해석 - 핸드 레이핑 - AbstractDetectingUrlHandlerMpapping 시리즈 초기화>
해야 할 일 :
1. detecthandlers를 호출하여 initApplicationContext를 덮어 쓰면 OBJCT를 스캔합니다
2. hook 방법 제공 핸들러에 따라 서브 클래스에 대한 서브 클래스에 대한 grongeUrlsForHandler
3. 부모 클래스의 레지스터 핸들러에게 전화하여 등록
@OverRidePublic void initApplicationContext ()는 ApplicationContexTexception {super.initApplicationContext (); detecthAndlers ();} Protected void detecthandlers ()를 BeanSexception {// ...}/*** 주어진 핸들러에 대한 URL을 결정합니다. AbstractControllerUrlHandlerMpapping, 이것은 확장되지 않았습니다. 자세히 이동하십시오 <springmvc 소스 코드 해석 - 핸드 레이핑 - AbstractDetectingUrlHandlerMpapping 시리즈 초기화> 구체적으로해야 할 일;
1. 결정을 내리고 일부 클래스를 제거하기 위해 로직을 추가하고 구성 파일에 구성된 제외 클래스 및 제외 패키지를 사용하기 위해 DecienturlSforHandler를 덮어 씁니다.
2. 컨트롤러의 서브 클래스 여부를 결정하십시오
3. 서브 클래스에 대한 URL을 생성하기 위해 BuildUrlsforHandler를 예약하십시오
@OverRideProtected String [] goundurlsforHandler (String BeanName) {class beanclass = getApplicationContext (). getType (beanname); if (iseligibleFormapping (beanname, beanclass)) {return buildUrlsforHandler (beanname, beanclass) {return null;} protected boolean, iselizected; 클래스 BeanClass) {} Protected Boolean iscontrollerType (클래스 BeanClass) {} Protected acpract String [] buildUrlsForHandler (String BeanName, Class BeanClass); ControllerBeanNameHandlerMpapping 및 ControlLerClassNameHandlerMpapping 소스 코드를 직접 살펴 보거나 <SpringMVC 소스 코드 해석 - 핸드 레이핑 - AbstractDetectingUrlHandlerMpapping Series Initialization>에서 이동하십시오. SimpleUrlHandLermpapp 구성 파일에서 handler에 URL을 직접 구성합니다.이 파일은 RegisterHandlers를 사용하여 구성 문서에서 핸들러를 등록하거나 코드를 직접 읽거나 <SpringMVC 소스 코드 해석 - 핸드 레이핑 - SimpleUrlHandlerMpapping 초기화>입니다.
BeanNameUrlHandlerMpapping emplesments grongeUrlsforHandler URL을 생성하거나 코드를 직접 보거나 <SpringMVC 소스 코드 해석 - 처리 - AbstractDetectingUrlHandlerMpapping Series Initialization>
주석을 기반으로 @Controller 사용, @requestmapping
가장 단단한 뼈
클래스 상속을 먼저 살펴 보겠습니다
각 범주의 책임에 대해 이야기 해 봅시다. 구체적인 분석은 다음 기사로 이동하십시오
<SpringMVC 소스 코드 해석 - 핸드 레이핑 - 요청 맵핑 핸드머핑 초기화>
<SpringMVC 소스 코드 해석 - 핸드 레이핑 - 요청 맵핑 핸드버핑 요청 배포>
1. AbstracthandLermethodMaping 초기화 프로세스와 요청시 매핑 방법을 정의합니다.
초기화 :
1.1.1 응용 프로그램에서 객체를 스캔합니다
1.1.2 Ishandler 후크 방법을 서브 클래스에 예약하여 객체가 핸들러인지 확인하십시오.
1.1.3 반복적으로 각 핸들러를 스캔하여 요구 사항을 충족하는 메소드를 찾으십시오. 여기의 판단은 여전히 서브 클래스에 맡겨져 있습니다.
1.1.4 발견 된 프로세서를 등록 할 때는 일치하는 조건 요청 MappingInfo가 핸들러에만 매핑 될 수 있는지 확인해야합니다.
1.1.5 일치하는 조건에 따라 URL을 받으면 프로세스를 정의하는 것입니다. 특정 알고리즘은 서브 클래스에 맡겨져 getMappingPathPatterns를 구현합니다.
요청 분배 처리 :
1.2.1 직접 문자열 일치 방법, 핸들러를 찾으십시오
1.2.2 일치 조건 검색, 여기의 특정 알고리즘은 서브 클래스로 전달되어 GetMatchingMapping
1.2.3 정렬하고 가장 잘 어울리는 핸들러를 얻으십시오. 여기서 정렬 방법은 여전히 서브 클래스 처리 GetMappingConparator입니다.
1.2.4 핸들러 일치 및 일치하지 않는 캡슐화
2. requestMappingInfoHandlerMpapping requestMappingInfo를 사용하여 일치 조건을 구현하고 요청 mappingInfo의 초기화가 서브 클래스에 맡겨집니다.
2.1 requestMappingInfo에 따라 URL-> getMappingPathPatterns를 생성합니다
2.2 일치 조건을 사용하여 핸들러를 찾으십시오 -> GetMatchingMapping
2.3 비교기 알고리즘 -> GetMapping Comparator
2.4 Handlematch 및 캐시를 덮어 쓰기 n 다중 정보 요청
등록 패턴, 최상
2.1.5 Handlernomatch를 덮어 쓰고 마지막 투쟁 후에 다시 일치 시키십시오.
3. requestMappingHandLerMpapping @Controller @RequestMapping에 따라 requestMappingInfo를 생성하고 ISHANDLER를 확인합니다.
3.1 aperpropertiesset를 덮어 쓰고 판단 할 파일 접미사를 추가하십시오
3.2 구현 ISHANDLER, 클래스의 주석 중 하나가 정확합니다.
3.3 주석 내용을 분석하고 인스턴스를 요청합니다