Abstract DetectingUrlHandlermapping Registers Handler a través del escaneo, y es distribuido por el Gethandlerinternal de abstractUrlHandlermapping al recibir la solicitud.
Hay 5 subclases y una clase abstracta.
Similar a SimpleUrlHandlermapping, se inicializa sobrescribiendo el initApplicationContext y luego llamando a los detectores.
Detechandlers escanean el objeto de aplicación a través de BeanFactoryUtils, y luego reserva el DetermlsForHandler para que la subclase genere la URL correspondiente de acuerdo con el controlador.
El registro registrado todavía se proporciona con resumenRlHandLermapping.
// abstractDetectingUrlHandlermapping/*** llama al método {@link #DetEtThandLers ()} además de la inicialización de*superclass.*/@overridepublic void initApplicationContext () lanza AplicationContextException {Super.initApplicationContext (); DetEcthandlers ();} Esto también se llama Interceptor de inicialización de InitApplicationContext de AbstractthandLermapping.
Aparece el protagonista, los detectores, los manejadores de escaneo
// abstractDetectInGurlHandlermapping/*** Registre todos los manejadores encontrados en la aplicación actual. Un frijol para* que no se pudieran determinar tales URL simplemente no se considera un controlador.* @Throws org.springframework.beans.beansexception Si el controlador no se puede registrar* @see #determineUrlsforHandler (string)*/Protected void DetecThandLers () tira behorSexception {si (logger.isdeBenBenAbenActibe ())))) {logger.debug ("Buscando asignaciones de URL en el contexto de la aplicación:" + getApplicationContext ());} string [] beanNames = (this.detEtThandLersInancEstorcontexts? BeanFactoryUtilss.BeanNamesFortypeCludEdedEdedEntors (getApplicationContext (), objeto) : getApplicationContext (). getBeanNamesFortype (objeto.class)); // Tome cualquier nombre de frijoles que podamos determinar URL para (String BeanName: BeanNames) {String [] urls = DetermlsSforHandler (BeanName); if (! ObjectuTils.isEmpty (urls)) {// rutas de url encontradas: consideremos un handler.registerHandler (urls, beanName);} else {if (logger.isdeBugeNabled ()) {logger.debug ("nombre de bean rechazado '" + beanName + ": no url rutas identificadas");}}}}}}}}}}}}}}}}}}}}}}}}} El método de plantilla reservado aquí se define de la siguiente manera:
/*** Determine las URL para el frijol de controlador dado.* @Param beanName el nombre del frijol candidato* @return las urls determinadas para el bean,* o {@code null} o una matriz vacía si ninguna*/cadena abstracta protegida [] determinaRlsforHandler (string beanName); Echemos un vistazo a la implementación del método de plantilla en BeanNameUrlHandlermapping y AbstractControllerUrlHandlermapping. BeanNameUrlHandlermapping es muy simple, por lo que implementa DetermlsForHandler. El alias en él debe configurarse en el archivo de configuración a través de BeanName.// BeanNameUrlHandlermapping/*** Comprueba el nombre y los alias de la frijol dada para las URL, comenzando con "/".*/@overrideProtected String [] DetermlSSForHandler (String BeanNeM {urls.add (beanName);} string [] aliases = getApplicationContext (). getAliases (beanName); for (alias de cadena: alias) {if (alias.startswith ("/")) {urls.add (alias);}} return stringUtils.ToStringarArray (urls);} Echemos un vistazo a la implementación en AbstractControllerUrlHandlermapping
IseligibleFormapping determina si el controlador está excluido (excluido a través del paquete de paquete o clase de clase).
BuildUrlsforHandler implementa reglas de generación de URL específicas de las subclases
IsControllerType determina si la subclase del controlador
Método de plantilla de reservas de BuildUrlsforHandler para URL de producción de subclase.
// abstractControllerUrlHandlermapping/*** Esta implementación delega a {@link #BuildurlsShandler},*proporcionó que {@link #IseligibleFormapping} devuelve {@code truehhth. getApplicationContext (). getType (beanName); if (isEligibleFormapping (beanName, beanClass)) {return buildUrlsforHandler (beanName, beanClass);} else {return null;}} // abstractRollerUrlHandlMapping/** Solo determina si el controlador se excluye de este mape. @param beanClass La clase concreta del controlador bean* @return si la clase especificada está excluida* @see #setExCludedPackages* @see #setExCludedClasses*/protegido boolean iseligibleFormapping (string beanName, class beanClass) {si (beanClass == null) {if (logger.isdeBugenBeBenBeNBeN ())) {logger.debug ("excluir el controlador bean '" + beanName + "' de la asignación de nombre de clase" + "porque su tipo de frijol no podría determinarse");} return false;} if (this.excludedClasses.contains (beanClass)) {if (logger.isDebugeNabled () {logger.deBug ("rechuded controlador Mapeo de nombre de clase " +" porque su clase Bean se excluye explícitamente: " + beanclass.getName ());} return false;} string beanClassName = beanclass.getName (); for (string packageName: this.ExcludedPackages) {if (beanClassSassAss.Starswitswith (paquete)) {logger.deBug ("excluir el controlador bean '" + beanName + "' de la asignación de nombre de clase" + "porque su clase de bean se define en un paquete excluido:" + beanclass.getName ());} return false;}} return isControllerType (beanClass);} // abstractControllerlhandlermappesping/*** Determinar si el controlador de bean* que dada es un control de bean* que es un controlador dada. mediante esta estrategia de mapeo.*@param beanClass la clase a introspectar*/protegido boolean isControllerType (class beanClass) {return this.predicate.isControllerType (beanClass);} // contractertypePePredicate proporciona 2 API para determinar si es un subclass de controlador o un subclass de multicultura. @Author JUERGEN HOELLER* @since ..*/class ControlerTypePredicate {public Boolean IsControllerType (class BeanClass) {return Controller.class.isassignableFrom (beanClass);} public boolean isMultiActionControllerType (class beanClass) {return multiActionController.isassignableFrom ( Reserve el método de plantilla para generar URL
// abstractControllerUrlHandlermapping/*** Método de plantilla de abstracto para ser implementado por subclases.* @Param beanName El nombre del bean* @param beanClass el tipo de bean* @return las URL determinadas para el bean*/protegido abstract string [] buildUrlsforhandler (string beanName, class beanClass);
Echemos un vistazo a las dos implementaciones de AbstractControllerUrlHandlermapping ControlerBeanNameUrlHandlermapping y ControllerClassNameUrlHandLermapping.
De hecho, estos dos son muy simples. Una es producir URL basada en BeanName, y la otra es producir URL basada en ClassName.
// controlerBeanNameUrlHandlermapping@overRideProtected String [] buildUrlSForHandler (string beanName, class beanClass) {list <string> urls = new ArrayList <String> (); urls.add (generatePathMapping (beanName); string [] aliases = getApplicationContex alias: aliases) {URLS.Add (generatePathMapping (alias));} return stringUtils.ToStringarArray (urls);} // controlerBeanNameUrlHandlermapping/** Agregar un '/' si se requiere y agrega el sufix de URL al nombre.*/protegido generatePathMapping (string beAryName) {string name = (beanName.startswith ("/")? BeanName: "/" + beanName); stringBuilder path = new StringBuilder (); if (! Name.Startswith (this.urlprefix)) {path.append (this.urlprefix);} path.append (name); if (! name.endswith (this.urlsuffix) {Path.Append (this.UrlSuffix);} return Path.ToString ();} // ControllerClassNameUrlHandLermapping Delegar directamente para generar implementación
@OverrideProtected String [] buildUrlsforHandler (String BeanName, Class BeanClass) {return GeneratePathMappings (beanClass);} // ControllerClassNameUrlHandlermapping Obtenga el prefijo de camino a través de BuildPathPrefix
Obtenga ClassName a través de classUtils, como BookController (sin nombre del paquete), y use el proxy CGLIB para resolver el problema juntos.
Convertir classname de acuerdo con si el caso es sensible (casos predeterminados sensibles = false;)
IsMultiActionControllerType determina si el controlador es una subclase de MultiActionController, es decir, si el controlador contiene múltiples manejadores.
/*** Genere las rutas de URL reales para la clase de controlador dada.* <P> Las subclases pueden optar por personalizar las rutas que se generan* anulando este método.* @Param beanClass la clase de frijol del controlador para generar una asignación para* @@return la ruta mapas de ruta para el controlador dado*/string protegido [] generatepathmappings (class beanClass) {string string boathmappings = buildPathPrefix (beanClass); string classname = classUtils.getShortName (beanClass); string path = (classname.endswith (controler_suffix)? classname.substring (, classname.lastIndexOf (controler_suffix): classname); if (path.lengther {pathMapping.append(path.substring(, ).toLowerCase()).append(path.substring());}else {pathMapping.append(path.toLowerCase());}}if (isMultiActionControllerType(beanClass)) {return new String[] {pathMapping.toString(), pathMapping.toString() + "/*"};} else {return new String [] {PathMapping.ToString () + "*"};}} // ControleClassNameUrlHandlermapping/*** Construya una ruta prefix de ruta de ruta. StringBuilder BuildPathPrefix (Class BeanClass) {StringBuilder pathmapping = new StringBuilder (); if (this.PathPrefix! = NULL) {PathMapping.Append (this.PathPrefix); PathMapping.Append ("/");} más PackageName = classUtils.getPackageName (beanClass); if (packageName.startswith (this.basepackage)) {String subpackage = packageName.substring (this.basepackage.length ()). Reemplazar ('.', '/')) subpackage: subpackage.tolowercase ()); pathmapping.append ("/");}} return PathMapping;} // AbstractControllerUrlHandlermapping Predicate.ImultiActionControllerType Implementación específica Consulte ControlerTypePredicate arriba
/*** Determine si la clase de frijol dada indica un tipo de controlador* que se envía a múltiples métodos de acción.* @Param beanClass la clase a introspecto*/protegido boolean isMultiActionControllerType (class beanClass) {return this.predicate.IsmultiActionControllerType (beanclass);}Lo anterior es el conocimiento relevante sobre la inicialización de la interpretación del código fuente de SpringMVC de la serie Handlermapping - Abstract DetectingUrlHandlermapping que el editor le presentó. ¡Espero que sea útil para todos!