【spring原始碼學習】springMVC之對映,攔截器解析,請求資料注入解析,DispatcherServlet執行過程

Love Lenka發表於2017-08-01

【一】springMVC之url和bean對映原理和原始碼解析 對映基本過程

(1)springMVC配置對映,需要在xml配置檔案中配置<mvc:annotation-driven >  </mvc:annotation-driven>

(2)配置後,該配置將會交由org.springframework.web.servlet.config.MvcNamespaceHandler處理,該類會轉交給org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser做解析。

(3)AnnotationDrivenBeanDefinitionParser做解析後,會向IOC容器中註冊多個物件。其中有這個物件org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

(4)RequestMappingHandlerMapping物件在IOC例項化bean階段,會呼叫該物件afterPropertiesSet()方法做url和bean的對映。

(5)該對映是從IOC中找到標註有@Controller,@RequestMapping註解的bean,然後反射所有的方法Mehod物件和註解中配置的url值進行對映。

(6)在org.springframework.web.servlet.DispatcherServlet初始化呼叫init()方法,在IOC解析,aop編制好後,會呼叫initStrategies(ApplicationContext context) 方法裡呼叫initHandlerMappings(context)中。將IOC中所有實現HandlerMapping介面的bean注入到dispatcherServlet屬性List<HandlerMapping> handlerMappings中

 

 

 

【二】springMVC攔截器的注入即應用的原理解析

(1)MvcNamespaceHandler在解析<mvc:annotation-driven ></mvc:annotation-driven>時向IOC容器中註冊RequestMappingHandlerMapping

(2)MvcNamespaceHandler在解析<mvc:interceptors> </mvc:interceptors>時向IOC容器中註冊一個個org.springframework.web.servlet.handler.MappedInterceptor攔截器物件

(3)RequestMappingHandlerMapping類是實現ApplicationContextAware介面的類,會在例項化的時候執行setApplicationContext(ApplicationContext context)方法,該方法內部初始化攔截器.將IOC容器中所有的MappedInterceptor物件賦值給RequestMappingHandlerMapping類的繼承下來的屬性private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();中

(4)未來在客戶端傳送請求,匹配到controller的時候會在RequestMappingHandlerMapping內部找到這個controller路徑符合的攔截器,執行。並快取起來。

 

【三】springMVC之請求資料注入Controller方法原理解析

(1)在載入IOC容器的時候,解析xml配置檔案,解析到<mvc:annotation-driven >  </mvc:annotation-driven>配置後,會向IOC容器中註冊一個物件org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

(2)同時會解析<mvc:message-converters register-defaults="true">配置,看是否有自定義的注入轉換器。如果有,並且register-defaults=false,則就使用配置的注入轉換器。如果register-defaults=true,則預設還會新增多個spring框架預設的注入轉換器。將注入轉換器載入到IOC容器中。舉例如下(不全)

org.springframework.http.converter.ByteArrayHttpMessageConverter

org.springframework.http.converter.StringHttpMessageConverter

org.springframework.http.converter.ResourceHttpMessageConverter

org.springframework.http.converter.xml.SourceHttpMessageConverter

org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter

(3)將這些注入轉換器形成一個集合。賦值給RequestMappingHandlerAdapter的屬性messageConverters。

(4)在IOC容器例項化RequestMappingHandlerAdapter的方法的時候,會呼叫afterPropertiesSet()方法做初始化操作。會將注入器包裝成 RequestResponseBodyMethodProcessor物件放入List<HandlerMethodArgumentResolver>,賦值給this.argumentResolvers屬性。

(5)在網路請求過來的時候,會根據反射得到要執行的controller方法的引數列表。根據引數列表,找到合適的HttpMessageConverter去從HttpserveltRequest中讀取請求體,然後進行引數組裝。將所有的引數列表組裝成資料。然後反射執行Controller方法。
(6)執行完Controller的方法後,會呼叫屬性returnValueHandlers(也會把HttpMessageConverter包裝RequestResponseBodyMethodProcessor物件加入List<HandlerMethodReturnValueHandler> handlers中賦值給該屬性)。進行相應的回撥操作。

 

 【四】DispatcherServlet執行網路請求,轉發致Controller的大致過程

 (1)幾個關鍵的物件

==>org.springframework.web.servlet.HandlerMapping介面實現類org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

    >>該物件是做url和controller的對映作用。同時還存放了攔截器的配置。

 >>在解析xml配置 <mvc:annotation-driven >時候spring會編碼方式注入IOC容器,在IOC容器例項化的時候會呼叫afterPropertiesSet()方法初始化對映關係。呼叫setApplicationContext()方法的時候初始化攔截器配置。

 

==>org.springframework.web.servlet.HandlerAdapter介面實現類org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

  >>該物件包換了http請求注入轉換器,http響應注入轉換器。

 

(2)DispatcherServlet執行過程

==>http請求進入,先透過HttpServeleRequest物件從DispatcherServlet屬性List<HandlerMapping> handlerMappings中獲取攔截器鏈子,請求執行的Controller包裝類HandlerExecutionChain mappedHandler。

==>然後根據HandlerExecutionChain mappedHandler 從List<HandlerAdapter> handlerAdapters中獲取一個RequestMappingHandlerAdapter

==>執行攔截器請求前的方法preHandle方法

==>RequestMappingHandlerAdapter呼叫handle方法執行請求。(注入,反射執行controller方法)

==>執行攔截器請求前的方法postHandle方法

 

 

 

【五】<mvc:annotation-driven >  </mvc:annotation-driven>配置,由AnnotationDrivenBeanDefinitionParser解析會在IOC中註冊的bean大致如下

【1】org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
屬性:
org.springframework.web.accept.ContentNegotiationManagerFactoryBean

【2】org.springframework.web.bind.support.ConfigurableWebBindingInitializer
屬性:
org.springframework.format.support.FormattingConversionServiceFactoryBean
org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean

【3】org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
屬性:
contentNegotiationManager:org.springframework.web.accept.ContentNegotiationManagerFactoryBean
webBindingInitializer:  org.springframework.web.bind.support.ConfigurableWebBindingInitializer
messageConverters : 下面

 

【4】<mvc:message-converters register-defaults="true">
==>org.springframework.http.converter.ByteArrayHttpMessageConverter(預設載入)
==>org.springframework.http.converter.StringHttpMessageConverter(預設載入)
==>com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter(配置)

==>org.springframework.http.converter.ResourceHttpMessageConverter(預設載入)
==>org.springframework.http.converter.xml.SourceHttpMessageConverter(預設載入)
==>org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter(預設載入)

==> org.springframework.http.converter.feed.AtomFeedHttpMessageConverter(不載入)
==>org.springframework.http.converter.feed.RssChannelHttpMessageConverter(不載入)

==>org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter(不載入)
==>org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter(預設載入)
==>org.springframework.http.converter.json.GsonHttpMessageConverter(不載入)

【5】org.springframework.web.servlet.config.CompositeUriComponentsContributorFactoryBean
屬性:
handlerAdapter:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
conversionService:org.springframework.format.support.FormattingConversionServiceFactoryBean


【6】org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor
【7】org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
【8】org.springframework.web.servlet.handler.MappedInterceptor
【9】org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
【10】org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
【11】org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
【12】org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
【13】org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter

相關文章