scanning을 통한 handlers handler and acpractDectingUrlHandlerMapped and arbospteCtingUrlHandlerMappe는 요청을 수신 할 때 AbstractUrlHandlerMpapping의 gethandlerinternal에 의해 배포됩니다.
5 개의 서브 클래스와 1 개의 추상 클래스가 있습니다.
SimpleUrlHandlerMpapping과 유사하게 InitApplicationContext를 덮어 쓰고 DetecThandLers를 호출하여 초기화됩니다.
DecThandler는 BeanFactoryUtils를 통해 응용 프로그램 객체를 스캔 한 다음 핸들러에 따라 해당 URL을 생성하기 위해 서브 클래스를 위해 DecienturlSforHandler를 예약합니다.
등록 된 레지스터 핸들러는 여전히 AbstractUrlHandlerMpapping에 의해 제공됩니다.
// AbstractDetectingUrlHandlerMpapp/***는*superclass의 초기화 외에 {@link #detecthandlers ()} 메소드를 호출합니다. 이를 AbstracthandLermpapping의 InitApplicationContext 초기화 인터셉터라고도합니다.
주인공이 나타납니다
// AbstractDetectingUrlHandlerMpapp/*** 등록 현재 ApplicationContext에있는 모든 핸들러 등록.* <p> 핸들러의 실제 URL 결정은 콘크리트* {@link #determineurlsforHandler (String)} 구현에 달려 있습니다. 그러한 URL을 결정할 수없는 콩은 단순히 핸들러로 간주되지 않습니다.* @throws org.springframework.beans.beansexception 핸들러를 등록 할 수없는 경우* @see #determineurlsforhandler (string)*/protected void detecthandlers () beansexception {). {logger.debug ( "응용 프로그램 컨텍스트에서 URL 매핑을 찾고 있습니다." + getApplicationContext ());} string [] beannames = (this.detecthAndlersinancestorContexts? beanfactoryUtils.BeannamesfortypeNcludedAncestors (getApplicationContext (), object.class) : getApplicationContext (). getBeannamesfortype (object.class)); // urls for.for (string beanname : beannames) {string [] urls = gongerlsforHandler (beanname); if (! objectUtils.isempty (urls)) {// url 경로 찾기 : handler.registerHandler (urls, beanname);} else {if (logger.isdebugenabled ()) {logger.debug ( "거부 된 bean 이름 '" + beanname + "'}})}}}}}}}}}}}}. 여기에 예약 된 템플릿 메소드는 다음과 같이 정의됩니다.
/*** 주어진 핸들러 Bean의 URL을 결정하십시오.* @param beanname 후보 bean의 이름* @bean에 대해 결정된 URL,* 또는 {@code null} 또는 none*/protected arbosp string [] goundurlsforhandler (String beanname); BeannameurlHandlerMpapping 및 AbstractControllerUrlHandlerMpapping에서 템플릿 메소드의 구현을 살펴 보겠습니다. BeannameurlHandlerMpapping은 매우 간단하므로 결정을 구현합니다. alias는 beanname.// beannameurlhandlermpapping/*** URL에 대한 주어진 Bean의 이름과 별명을 확인하여 "/"./@overrideprotected string [] goundurlsforHandler (list <string> urls = new ArrayList <string> ()로 시작하여 구성 파일에서 구성되어야합니다. (beanname.startSwith ( "/")) {urls.add (beanname);} string [] aliases = getApplicationContext (). getAliases (beanname); for (string alias : aliases) {if (alias.startSwith ( "/")) {urls.add (alias);}} return stringUtils.toStringArray (urls);} AbstractControllerUrlHandlerMpapping의 구현을 살펴 보겠습니다
ISELIGIBLEFORMAPPING 컨트롤러가 제외되는지 (패키지 패키지 또는 클래스 클래스를 통해 제외)를 결정합니다.
BuildUrlsForHandler는 서브 클래스에서 특정 URL 생성 규칙을 구현합니다
ISControllerType는 컨트롤러의 서브 클래스 여부를 결정합니다
BuildUrlsForHandler 서브 클래스 생산 URL에 대한 템플릿 방법.
// AbstractControllerUrlHandlerMpapping/***이 구현 대의원은 {@link #buildurlsforhandler}에 대의원합니다. {@link #iseligibleformapping} retrings {@code prue} .*/@overrideprotected string [] gounderurlsforhandler (String Beanname) {class beanclass = {class beanclass = getApplicationContext (). getType (beanname); if (iseligibleformapping (beaname, beanclass)) {return buildUrlsforHandler (beanname, beanclass);} else {return null;}} // 컨트롤러 가이 맵핑에서 제외되었는지 여부를 결정합니다. @param beanclass 지정된 클래스가 제외되는지 여부* @see #setexcludedPackages*/setexCludedClass*/protected boolean iseligibleformapping (string beanname, class beanclass) {if (beanclass == null) {if (logger.isdebugenabled (if) {logger.debug ( "컨트롤러 Bean 제외" " + Beaname +" 'rete bean + "에서" + "에서" + "가 결정할 수 없기 때문에" + ";} return false;} if (this.excludedClass.contains (beanclass)) {if (logger.isdebugenabled ()) {logger.debug (" + bean "" + bean "" "" + bean "" "{" "{excluded exe Bean. " +"가 명시 적으로 제외되기 때문에 " + beanclass.getname ());} retract false;} string beanclassname = beanclass.getname (); for (string packagename : this.excludedpackages) {if (beanclassname.startswith (packagename))) {logger (logger.isdebugended ()) {logger.debug ( "컨트롤러 Bean 제외" " + beaname +" ' + "에서 Bean 클래스가 제외 된 패키지에 정의되어 있기 때문에 클래스 이름 매핑" + "에서" + "}}} iscontrollertype (beanclass);} // excertControllHhandlerMping/* eboctOntrollerlmping/***를 결정하는지 여부를 결정합니다. 이 매핑 전략에 의해 지원됩니다.*@param beanclass 클래스는 내성적 인 부화*/보호 된 부울 iscontrollertype (class beanclass) {retract this.predicate.iscontrollertype (beanclass);} // controllertyprepredicate가 컨트롤러의 서브 클래스 또는 서브 클래스의 서브 클래스인지 여부를 결정하기 위해 2 개의 API를 제공합니다. 컨트롤러 유형. ** @Author Juergen Hoeller* @Since ..*/클래스 컨트롤러 타입 영광 {public boolean iscontrollertype (class beanclass) {return controller.class.isassignablefrom (beanclass);} public boolean ismultiacect controllertype (class beanclass) {reture retur MultiacectController.class.isAssignableFrom (BeanClass);}} URL을 생성하려면 템플릿 방법을 예약하십시오
// subclass에 의해 구현 될 AbstractControllerUrlHandlerMpapping/*** 초록 템플릿 메소드.* @Param Beanname Bean의 이름* @param beanclass bean의 유형* @bean*/protected string [] buildurlsforhandler (String beanname, class beanclass);
AbstractControllerUrlHandlerMpapping ControlLerBeanNameUrlHandlerMpapping 및 ControlLerClassNameUrlHandlerMpapping의 두 구현을 살펴 보겠습니다.
실제로이 두 가지는 매우 간단합니다. 하나는 BeanName을 기반으로 URL을 생성하고 다른 하나는 ClassName을 기반으로 URL을 생성하는 것입니다.
// controllerBeanNameUrlHandlerMpapped@attrestrideprotected string [] buildUrlsforHandler (String beanname, class beanclass) {list <string> urls = new arrayList <string> (); urls.Add (생성 [] aliases =]) alias : aliases) {urls.add (generatepathmapping (alias));} return stringUtils.toStringArray (urls);} // 컨트롤러 비안 NAMEURLHANDLERMAPP/** 필요한 경우 a '/'를 추가하고 URL을 이름에 부여합니다. beanname : "/" + beanname); StringBuilder path = new StringBuilder (); if (! name.startSwith (this.urlpRefix)) {path.append (name); if (! path.toString ();} // controllerclassnameurlhandlermpapping 직접 위임하여 Pathpitmappings 구현을 생성합니다
@OverRideProtected String [] buildUrlSforHandler (String BeanName, Class BeanClass) {return GeneratePathMappings (BeanClass);} // ControllerClassNameUrlHandlerMpapping BuildPathPrefix를 통해 경로의 접두사를 가져옵니다
BookController (패키지 이름이없는)와 같은 ClassUtils를 통해 클래스 이름을 얻고 CGLIB 프록시를 사용하여 문제를 해결하십시오.
케이스가 민감한 지 여부에 따라 className을 변환하십시오 (기본 caseEnsentive = false;)
ismultiactionControllerType 컨트롤러가 MultiacectionController의 서브 클래스인지, 즉 컨트롤러에 여러 핸들러가 포함되어 있는지 여부를 결정합니다.
/*** 주어진 컨트롤러 클래스에 대한 실제 URL 경로를 생성합니다.* <p> 서브 클래스는이 방법을 재정의하여 생성 된 경로를 사용자 정의 할 수 있습니다.* @Param Beanclass 컨트롤러 Bean 클래스* @return 주어진 컨트롤러에 대한 URL 경로 매핑을 생성합니다*/protected String [] generatebuilder at pathmaping = generatebuilder ratmaping =. buildPathPrefix (beanclass); String className = classUtils.getShortName (beanclass); String path = (controller_suffix)? className.SubString (, className.lastIndexOf (controller_Suffix)); if (path.length ()>) {if (this.caseSendition) {pathMapping.append (path.SubString () .tolowercase ()). append (path.substring ());} else {pathMapping.append (path.tolowercase ());}} if (ismultiActionControllerType (BeanClass)) {return new String [] {pathmapping.toString (), Patostring (), PathMapping. "/*"};} else {return new String [] {pathmapping.toString () + "*"};}} // 컨트롤러 ControllerClassNameUrlHandlerMpapp/*** 주어진 컨트롤러 Bean 클래스에 대한 경로 접두사 구축. StringBuilder buildPathPrefix (class beanclass) {StringBuilder PathMapping = new StringBuilder (); if (this.pathprefix! = null) {pathMapping.append (this.pathPrefix); theathmapping.append ( "/"); else {pathmapping.append ( "/"); packagename = classutils.getPackagename (beanclass); if (packagename.startswith (this.basepackage)) {String subpackage = packagename.substring (this.basepackage.length ()). ( '.', '/'); pathmapping.appendecensitive? 서브 포장 : subpackage.tolowercase ()); PathMapping.append ( "/");}} return pathmapping;} // acpractControllerUrlHandlerMpapping Precticate.ismultiactioncontrollerType 특정 구현 위의 ControlLerTypepredicate를 참조하십시오
/*** 주어진 Bean 클래스가 여러 동작 방법으로 발산되는 컨트롤러 유형*을 나타내는 지 여부를 결정합니다.* @Param Beanclass Class를 내성적으로 보증*/보호 된 boolean ismultiactioncontrollertype (class beanclass) {return this.predicate.ismultiactioncontrollertype (beanclass);}위의 것은 편집기가 소개 한 핸드 레이 핑 - AbstractDetectingUrlHandlerMpapping 시리즈의 SpringMVC 소스 코드 해석 초기화에 대한 관련 지식입니다. 나는 그것이 모두에게 도움이되기를 바랍니다!