Visão geral
Para desenvolvedores da Web, o modelo MVC é muito familiar para todos. No SpringMVC, a solicitação que atenda às condições entra no DispatcheserServlet responsável pela distribuição da solicitação. O DispatcheserServlet mapeia o URL da solicitação para o controlador (salvar em manutenção). O Handlermapping finalmente retorna o HandlerexecutionChain, que contém o manipulador de objetos de processamento específico (ou seja, o que escrevemos quando o programamos). Controlador) e uma série de interceptores. No momento, o DispatcheserServlet encontrará um manipulador que suporta esse tipo de processador com base no manipulador no manipulador no HandlerexecutionChain devolvido. No adaptador do processador, ele chamará o método de resposta de solicitação do controlador e retornará a visualização do resultado (ModelAndView). Após obter a visualização do resultado, o resultado é exibido através do método de renderização.
Sistema de herança de Handermaping:
Springmvc solicita distribuição ao processador Handler. Esta etapa é resolvida através do módulo de manutenção. Manutenção também lida com interceptores.
Vamos dar uma olhada na árvore de herança de manipular primeiro
Você pode fazer uma classificação como esta:
1. Um manipulação de interface, defina uma API: HandlerexecutionChain Gethandler (solicitação httpServletRequest) lança exceção;
2. Uma classe abstrata básica: prepara principalmente o ambiente de contexto, fornece o gancho Gethandlerinternal, encapsula o interceptador à HandlerexecutionChain
3. Uso de @Controller, @RequestMapping com base na anotação
4. Configure o SimpleurlHandlerMapping do URL para o manipulador no arquivo de configuração
5. BeanNameurlHandlerMapping é implementado por padrão
6. Mapeamento de subclasses do controlador
Vamos dar uma olhada no Handlermapping, apenas uma API de Gethandler é muito simples.
// handlermappingpackage org.springframework.web.servlet; interface pública HandlerMapping {handlerexecutionChain Gethandler (httpServletRequest Solicy) lança exceção;} Abstracthandlermapping não é tão simples
Primeiro, olhe para a classe herdada por abstracia e a interface implementada
pacote org.springframework.web.servlet.handler; classe abstrata public abstractrandlermapping estende WebApplicationObjectSupportImplements Handlermapping, ordenado {// ...} WebApplicationObjectSupport é usado para fornecer ApplicationContext de contexto e ServletContext.
Há também o método InitApplicationContext aqui, que é frequentemente usado no futuro. Abstactandlermapping é substituído diretamente.
As interfaces ApplicationContexTAWare e ServletContextAware ainda são implementadas na classe pai e o conceito de primavera é muito unificado.
Ordenado é usado para classificação de coleções.
Vamos continuar analisando as propriedades do abstingo
// abstracthandlermapping // O pedido atribui o valor máximo, e a prioridade é a menor ordem privada int = integer.max_value; // Padrão: o mesmo que não ordenado // o manipulador padrão, o obejct usado aqui e a implementação da subclasse, use handlermethod, handlerexecutionchain e outro objeto privado defaultHandler; // classe auxiliar para cálculo de url privado urlpatheling urlpathelper = slowerpathing Pathport Pathport (PathMel PathMer (PathMel PathMer (PathMer PathMer PathMe (PathMel); new AntPathMatcher (); // Configuração do interceptador:, configuração de propriedades de manipulação;, ExtendInterceptores Defina a lista final privada <ject> interceptors = new ArrayList <ject> (); // parse de interceptores e adicione -o diretamente a todos os HandlerPrivate List <HandlerPort> AdapTeptEceptors/; Somente se a correspondência for aprovada será usada na lista final privada <MapedInterceptor> mapedInterceptores = new ArrayList <MapedInterceptor> ();
Confira a inicialização do interceptador:
// abstracthandlermapping@substituto prototected initapplicationContext () lança beansexception {extendInterceptores (this.interceptores); detectMapedInterceptors (this.MaPedInterceptores); initinterceptores (); {}/*** Scan the MappedInterceptors under the application and add them to mappedInterceptors*/protected void detectMappedInterceptors(List<MappedInterceptor> mappedInterceptors) {mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludedAncestors(getApplicationContext(),MappedInterceptor.class, true, false) .Values ());}/*** Colete o MappEdInterceptor e adapte -se ao HandlerInterceptor e WebRequestInterceptor*/Protected void initInterceptores () {if (! this.intercept.isempty ()) {para (int i =; i <this.inter.inter.size (); i ++) {object); null) {tire nova ilegalargumentException ("número de entrada" + i + "na matriz de interceptores é nulo");} if (instância interceptadora do mapedInterceptor) {mapedInterceptores.add} (mappedInterceptor) interceptor);} sen) {adapted)} AdaptInterceptor (Object Interceptor) {if (Instância interceptora de HandlerInterceptor) {return (HandlerInterceptor) interceptor;} else if (interceptor Instância de webRequestInterceptor) {return new WebRequestHandlerInterCortAlAdApter ((Web -septorCor) {interceptor); interceptor.getClass (). getName ());}}Depois, há a implementação do Gethandler (solicitação httpServletRequest) e aqui também reserva o GethandlerInternal (solicitação HTTPServletRequest) para implementação da subclasse.
// AbstacthandlerMappingPublic Final HandlerexecutionChain Gethandler (solicitação HttpServLeTrequest) lança exceção {manipulador de objetos = gethandlerinternal (request); if (manipulador == null) {handler = getDefaLTHandler ();} if (handler == null) {NULL) {NULL {NULL) {NULL) {NULL) {NULL) {NULL) {NULL). Instância de string) {string handlername = (string) handler; handler = getApplicationContext (). getBean (nome do manutenção);} retorna GethandleRexecutionChain (manipulador, solicitação);} realização do objeto abstrato GethandlerInternal (httpSleTleTequest request); Finalmente, encapsular o interceptador à HandlerexecutionChain
Adicione os interceptores adaptados diretamente
MappedInterceptores precisam ser adicionados após a correspondência de acordo com o URL
// AbstacthandlerMappingProtected handlerexecutionChain GethandlerexecutionChain (manipulador de objetos, httpServletRequest Request) {handlerexecutionChain Chain = (Instância do manipulador de handlerexecutionCain) manipulador: new HandleRexecutionChain (Handler); Chain.AddInterceptores (GetAdaptedInterceptores ()); String lookuppath = urlpathhelper.getLeoppathForRequest (request); para (MappEdInterceptor mapedInterceptor: mapedInterceptores) {if (mapepedIntercept.matches (LookuPath, pathmatcher)) {Chain.addintercept (mapedIntercept.getIntercept ());}} Cadeia de retorno;} O mapeamento das subclasses do controlador, este ramo primeiro analisa a herança da classe
Vamos falar sobre as principais responsabilidades de cada categoria aqui
1. Abstracthandlermapping Prepare o ambiente de contexto; fornecer gancho Gethandlerinternal; Encapsular interceptador à HandlerexecutionChain
2. AbstractUrlHandlerMapping implementa o método de registro do manipulador para uso da subclasse; implementa GethandlerInternal e encontra o manipulador com base nas informações de configuração inicializadas por subclasses.
3. AbstractDetectingUrlHandlerMapping Digitaliza o objeto sob o aplicativo e, após a iteração, fornece o método do gancho DeterminerlsForHandler para determinar como filtrá -lo.
4. AbstractControllerUrlHandlerMapping implementos DetermineRlsForHandler, adiciona a operação do manipulador (configuração do arquivo de configuração) e reserva o método do gancho BuildUrlsForHandler para implementação da subclasse; ao mesmo tempo julga a subclasse do controlador
5.
ControlerclassNameHandlerMapping gera URL com base no nome da classe
Vamos começar com abstrataurlhandlermapping. Aqui apenas olhamos para o código aproximadamente. Se você precisar analisá -lo com cuidado, vá para <Springmvc Código Fonte Interpretação - Handlemapping - AbstractUrlHandlerMapping Series Solicitação Distribuição>
Registro do manipulador
Protected void RegisterHandler (String [] urlpaths, string beanname) lança beansexception, ilegalStateException {} void de proteção protegido (string urlpath, objeto manipulador) lança beansception, ilegalstateException {} A busca por manipulador
Objeto protegido GethandlerInternal (solicitação httpServletRequest) lança Exceção {} // Encontre a LookupHandler de objeto HandlerProtected (String urlpath, httpServletRequest Solicy) lança exceção {} // verifique se a excepção de manutenção (} // verifique se há thterows) // {} // verifique se a excepção de manutenção (} // verifique se há (} // e verificou a exceção (} // e verificou a exceção (} // e a retenção de manutenção (} ///} // verificou a exceção (} // e verificou a exceção (} // e a retenção de manutenção (} ///} // verificou a exceção (} // verificada). HandlerexecutionChainProtected Object BuildPathExpositingHandler (Object RawHandler, String BestMatchingPattern, String PathWithInMapping, mapa <String, String> URITEMPLATEVARIABLES) {}AbstractDetectingUrlHandlerMapping, isso não é expandido, mova -se em detalhes <Springmvc Código -fonte Interpretação - Handlermapping - AbstractDetectingUrlHandlerMapping Series Inicialização>
O que fazer:
1. Ligue para os detecthandlers para digitalizar objct sobrescrevendo o InitApplicationContext
2. Forneça o método do gancho DetermineRlsForHandler para a subclasse gerar URLs de acordo com o Handler
3. Ligue para o RegisterHandler da classe pai para se registrar
@OverridePublic void initApplicationContext () lança ApplicationContextexception {super.initapplicationContext (); detectHandlers ();} void protegido detecthandlers () lança o dado border. beanname); AbstractControllerUrlHandlerMapping, isso não é expandido, mova -se em detalhes <Springmvc Código -fonte Interpretação - Handlermapping - AbstractDetectingUrlHandlerMapping Series Inicialização> O que fazer especificamente;
1. Substituir o determinar o Mandinato para adicionar lógica para remover algumas classes e usar as classes excluídas e excluídos de packages configurados no arquivo de configuração.
2. Determine se a subclasse do controlador
3. Reserve BuildUrlsForHandler para gerar URLs para subclasses
@OverrideProtected String [] determinarUrlsForHandler (String beanname) {classe beanclass = getApplicationContext (). iseligibleFormapping (string beanname, classe beansclass) {} protegido boolean iscontrollertype (classe beansclass) {} abstract string protegido [] buildurlsforHandler (string beanname, classe beanclass); ControllerBeanNameHandlerMapping e ControlClassNameHandlerMapping Olhe diretamente para o código -fonte ou mova <Springmvc Código -fonte Interpretação - Handlemapping - AbstractDetectingUrlHandlerMapping Inicialização da série> SimpurlHandlerMapping Configure diretamente o URL para o manipulador no arquivo de configuração, que é usar o RegisterHandlers para registrar o manipulador no documento de configuração, leia o código diretamente ou mova <Springmvc Código -fonte Interpretação - HandlemApping - Inicialização SimpleurlHandlerMapping>
Os implementos do BeanNameurlHandlerMapping determinam que os seguradores de idade geram URLs, observe o código diretamente ou mova <Springmvc Código -fonte Interpretação - Handlemapping - AbstractDetectingUrlHandlerMapping Inicialização da série>
Uso de @Controller, @RequestMapping com base na anotação
O osso mais difícil
Vejamos a herança da aula primeiro
Vamos falar sobre as responsabilidades de cada categoria. Para análises específicas, vá para o seguinte artigo
<Springmvc Código -fonte Interpretação - Handlemapping - RequestMappingHandlerMapping Inicialização>
<Springmvc Código -fonte Interpretação - Handlemapping - RequestMappingHandlerMapping Distribuição da solicitação>>
1. Abstracthandlermethodmaping define o processo de inicialização e como mapeá -lo ao solicitar
Inicialização:
1.1.1 Digitalizar o objeto sob o aplicativo
1.1.2 Reserve o método ISHandler Hook para subclasse para determinar se o objeto é manipulador
1.1.3 Digitalize iterativamente cada manipulador para encontrar um método que atenda aos requisitos. O julgamento aqui ainda é deixado para a subclasse para implementar o getMappFormethod
1.1.4 Ao registrar o processador encontrado, você precisa garantir que uma condição de condição correspondenteMapMapinFO só possa mapear para um manipulador
1.1.5 Obtenha o URL de acordo com as condições de correspondência e o mesmo é apenas para definir o processo. O algoritmo específico é deixado para a subclasse para implementar o getMappathPatterns
Solicitar processamento de distribuição:
1.2.1 Método de correspondência direta de string, procure manipulador
1.2.2 Pesquisa de condição correspondente, o algoritmo específico aqui é entregue à subclasse para getMatchingMapping
1.2.3 Classifique e obtenha o melhor manipulador correspondente. O método de classificação aqui ainda é o processamento de subclasse getMappingConparator
1.2.4 encapsulamento de manipuladores correspondentes e não correspondentes, respectivamente
2. RequestMappingInfoHandlerMapping usa o requestMappingInfo para implementar condições correspondentes, e a inicialização do requestMappingInfo é deixada para a subclasse
2.1 Gere URL -> getMappathPatterns de acordo com o requestmappingInfo
2.2 Encontre manipulador usando condições correspondentes -> getMatchingMapping
2.3 Algoritmo do comparador -> GetMappComParator
2.4 Substituir o Handlematch e o cache n várias informações para solicitar
Padrão de registro, melhor padrão de correspondência, parâmetros analisados em URL, parâmetros de vários valores analisados em URL, MediaType
2.1.5 substitua o handlernomatch, tente combiná -lo novamente após a última luta
3. RequestMappingHandlerMapping Gere RequestMappingInfo De acordo com o anotação @Controller @RequestMapping e verifique se o ISHandler
3.1 Substituir o AfterPropertiesset e adicionar sufixo de arquivo para julgar
3.2 Implementar o IsHandler e uma das anotações da classe está correta.
3.3 Analisar o conteúdo da anotação e produzir instâncias de requestmappingInfo