Use spring to implement class scanning under the package

Source: Internet
Author: User

There are a number of scenarios in which a package scan is needed in a project, typically when the project is initialized, and the classes under a certain packages are treated with special care. The function that I want to implement now is to scan the specified package path when a filter or interceptor is initialized, traverse each of the following classes, find out all the methods that use a special annotation on method, and then cache it, when the methods interceptor works , there is no need to judge whether the method needs to be intercepted.

There are many examples of your own code to implement the scan package, but if you have tools that have been implemented for you and have undergone universal validation, it is not necessary to build your own wheels.
Class Classpathbeandefinitionscanner with scan packages in spring frame the Findcandidatecomponents method is the basis for our transformation.

/** * scan the class path for candidate components. *  @param  basepackage the package to check for annotated classes * @ Return a corresponding set of autodetected bean definitions */public  set<beandefinition> findcandidatecomponents (string basepackage)  {    Set<beandefinition> candidates = new linkedhashset<beandefinition> ();    try {      String packageSearchPath =  resourcepatternresolver.classpath_all_url_prefix +             resolvebasepackage (basepackage)  +  "/"  + this.resourcePattern;       resource[] resources = this.resourcepatternresolver.getresources ( Packagesearchpath);   &Nbsp;   boolean traceenabled = logger.istraceenabled ();       boolean debugenabled = logger.isdebugenabled ();       for  (resource resource : resources)  {          if  (traceenabled)  {             Logger.trace ("scanning "  + resource);          }          if  (Resource.isreadable ())  {             try {                MetadataReader metadataReader =  This.metadataReaderFactory.getMetadataReader (Resource);                if  (Iscandidatecomponent (metadatareader))  {                   scannedgenericbeandefinition sbd = new  scannedgenericbeandefinition (Metadatareader);                   sbd.setresource (Resource);                   sbd.setsource (Resource);                   if  (Iscandidatecomponent (SBD))  {                      if  (debugenabled)  {                          logger.debug ("Identified candidate component class:  " + resource);                      }                       candidates.add (SBD);                   }                   else {                      if  (debugenabled)  {                          logger.debug ("ignored because not a concrete top-level class: "  + resource);                       }                   }               }                else {                   if  ( traceenabled)  {                      logger.trace ("ignored because not matching any  filter:  " + resource);                   }                }            }             catch  (Throwable ex)  {                throw new beandefinitionstoreexception (                        "failed to read candidate component class: "  + resource, &NBSP;EX);            }          }         else {             if  (traceenabled)  {                logger.trace ("Ignored because  not readable:  "&NBsp;+ resource);            }          }      }   }    catch  (Ioexception ex)  {      throw new  Beandefinitionstoreexception ("i/o failure during classpath scanning",  ex);    }   return candidates;}


The transformation is as follows:

The loadcheckclassmethods of the method is a comma-delimited package path, such as com.xx

Using Spring's

Resourcepatternresolver to find the resources under the package resource, because our scan pattern is a. class file, so here's resource is the class file protected static final String Default_resource_pattern = "**/*.class";
/** *   */private void loadcheckclassmethods (String) depending on the configuration  *  load of the scan package that needs to be checked  scanpackages)  {    string[] scanpackagearr = scanpackages.split ( ",");    resourcepatternresolver resourcepatternresolver = new  Pathmatchingresourcepatternresolver ();     metadatareaderfactory metadatareaderfactory  = new cachingmetadatareaderfactory (resourcepatternresolver);    for  ( String basepackage : scanpackagearr)  {        if   (Stringutils.isblank (basepackage))  {             continue;        }         string packagesearchpath = resourcepatternresolver.classpath_all_url_prefix +      &nBsp;          classutils.convertclassnametoresourcepath ( Systempropertyutils.resolveplaceholders (basepackage)  +  "/"  + DEFAULT_RESOURCE_PATTERN;         try {             resource[] resources = resourcepatternresolver.getresources ( Packagesearchpath);            for  (Resource  resource : resources)  {                 //Check resource, the resource here are class                 loadclassmethod (Metadatareaderfactory, resource);             }         } catch  (EXCEPTION&NBsp;e)  {            log.error (" Initialize Sensitivewordinterceptor failed ",  e);        }     }}
/** *  loading resources, judging the methods inside  * *  @param  metadataReaderFactory  Tools for reading resource as class in spring  *  @param  resource                The resources here is a class *  @throws  IOException */private  Void loadclassmethod (Metadatareaderfactory metadatareaderfactory, resource resource)   throws ioexception {    try {         if  (Resource.isreadable ())  {             metadatareader metadatareader = metadatareaderfactory.getmetadatareader (Resource);             if  (Metadatareader != null)  {                string  classname = metadatareader.gEtclassmetadata (). GetClassName ();                 try {                     trycachemethod (ClassName);                 } catch  (Classnotfoundexception e)  {                     log.error ("Check"  + className +  "do not contain required information failed",  e);                 }             }        }     } catch  (exception e)  {        log.error (" The method implementation in the judgment class needs to detect XXX failure ",  e);     }} 
/** *  all the method below the action to see if they need to verify the XXX  * , if necessary, into the cache  * *  @param  fullclassname */private void trycachemethod (String fullclassname)  throws  Classnotfoundexception {    class<?> clz = class.forname ( FullClassName);     method[] methods = clz.getdeclaredmethods ();     for  (method method : methods)  {         if  (Method.getmodifiers ()  != modifier.public)  {             continue;        }         if  (CheckXXX.class.isAssignableFrom (check_annotation))  {             CheckXXX checkXXX =  (checkxxx )  method.getannotation (Check_annotation);            if  (CheckXXX  != null && checkxxx.check ())  {                 cache.put (fullclassname +  ".")  + method.getname (),  checkxxx);                 log.info ("A method to check for XXX is detected:"  + fullClassName +  ".")  + method.getname ());            }         }    }}


What Trycachemethod do is cache the public method that needs to be handled.


Tested, this way can be taken to the Web class file and jar package in the class file

Use spring to implement class scanning under the package

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.