天天看點

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

【一】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