Java: how to scan all classes in a specified package

Source: Internet
Author: User

Java: how to scan all classes in a specified package

To write an MVC framework, you need to scan components from the package and register them in the container. JDK does not provide a ready-made slave method and can only be implemented by yourself.

Function:
Given a package name, you can program all the class files under the package (and all its sub-packages. For example, enter the package namecom.myapp.util, Output the full qualified name of the class under this packagecom.myapp.util.StringUtils,com.app.util.ImageUtils.

Ideas:
Some web servers decompress the jar package during deployment and running, so the class file will be in the normal file directory. If the web server does not support the jar package, the class file will directly exist in the Jar package. For the former, you only need to locate the directory where the class file is located, and then read the class file name. For the latter, You need to first locate the directory where the jar package is located, and then useJarInputStreamRead the Jar package and get the class name.

Implementation:
This is directly copied from the written project code. To run this code, you needLogger.debugChangeSystem.out.println()

/*** This operation is used to find out all classes in a package. * Created by whf on 15-2-26. */public class classpathpackage‑implements package‑{ private Logger logger = LoggerFactory. getLogger (classpathpackage.pdf. class); private String basePackage; private ClassLoader cl;/*** Construct an instance and specify the base package it shocould scan. * @ param basePackage The base package to scan. */public classpathpackage1_( String basePackage) {this. basePackage = basePackage; this. cl = getClass (). getClassLoader ();}/*** Construct an instance with base package and class loader. * @ param basePackage The base package to scan. * @ param cl Use this class load to locate the package. */public classpathpackageage (String basePackage, ClassLoader cl) {this. basePackage = basePackage; this. cl = cl;}/*** Get all fully qualified names located in the specified package * and its sub-package. ** @ return A list of fully qualified names. * @ throws IOException */@ Override public List
  
   
GetFullyQualifiedClassNameList () throws IOException {logger.info ("start scanning all classes under package {}", basePackage); return doScan (basePackage, new ArrayList <> ());} /*** Actually perform the scanning procedure. ** @ param basePackage * @ param nameList A list to contain the result. * @ return A list of fully qualified names. ** @ throws IOException */private List
   
    
DoScan (String basePackage, List
    
     
NameList) throws IOException {// replace dots with splashes String splashPath = StringUtil. dotToSplash (basePackage); // get file path URL = cl. getResource (splashPath); String filePath = StringUtil. getRootPath (url); // Get classes in that package. // If the web server unzips the jar file, then the classes will exist in the form of // normal file in the directory. // If the web server does not unzip the jar file, then classes will exist in jar file. list
     
      
Names = null; // contains the name of the class file. e.g ., apple. class will be stored as "Apple" if (isJarFile (filePath) {// jar file if (logger. isDebugEnabled () {logger. debug ("{} is a JAR package", filePath);} names = readFromJarFile (filePath, splashPath);} else {// directory if (logger. isDebugEnabled () {logger. debug ("{} is a directory", filePath);} names = readFromDirectory (filePath);} for (String name: names) {if (isClassFile (name )) {// nameList. add (basePackage + ". "+ StringUtil. trimExtension (name); nameList. add (toFullyQualifiedName (name, basePackage);} else {// this is a directory // check this directory for more classes // do recursive invocation doScan (basePackage + ". "+ name, nameList) ;}} if (logger. isDebugEnabled () {for (String n: nameList) {logger. debug ("find {}", n) ;}return nameList;}/*** Convert short class name to fully qualified name. * e.g ., string-> java. lang. string */private String toFullyQualifiedName (String shortName, String basePackage) {StringBuilder sb = new StringBuilder (basePackage); sb. append ('. '); sb. append (StringUtil. trimExtension (shortName); return sb. toString ();} private List
      
        ReadFromJarFile (String jarPath, String splashedPackageName) throws IOException {if (logger. isDebugEnabled () {logger. debug ("read class from JAR package: {}", jarPath);} JarInputStream jarIn = new JarInputStream (new FileInputStream (jarPath); JarEntry entry = jarIn. getNextJarEntry (); List
       
         NameList = new ArrayList <> (); while (null! = Entry) {String name = entry. getName (); if (name. startsWith (splashedPackageName) & isClassFile (name) {nameList. add (name);} entry = jarIn. getNextJarEntry ();} return nameList;} private List
        
          ReadFromDirectory (String path) {File file = new File (path); String [] names = file. list (); if (null = names) {return null;} return Arrays. asList (names);} private boolean isClassFile (String name) {return name. endsWith (". class ");} private boolean isJarFile (String name) {return name. endsWith (". jar ");}/*** For test purpose. */public static void main (String [] args) throws Exception {package1_scan = new classpathpackage1_( "cn. fh. lightning. bean "); scan. getFullyQualifiedClassNameList ();}}
        
       
      
     
    
   
  

The above code is usedStringUtilsClass:

public class StringUtil {    private StringUtil() {    }    /**     * "file:/home/whf/cn/fh" -> "/home/whf/cn/fh"     * "jar:file:/home/whf/foo.jar!cn/fh" -> "/home/whf/foo.jar"     */    public static String getRootPath(URL url) {        String fileUrl = url.getFile();        int pos = fileUrl.indexOf('!');        if (-1 == pos) {            return fileUrl;        }        return fileUrl.substring(5, pos);    }    /**     * "cn.fh.lightning" -> "cn/fh/lightning"     * @param name     * @return     */    public static String dotToSplash(String name) {        return name.replaceAll("\\.", "/");    }    /**     * "Apple.class" -> "Apple"     */    public static String trimExtension(String name) {        int pos = name.indexOf('.');        if (-1 != pos) {            return name.substring(0, pos);        }        return name;    }    /**     * /application/home -> /home     * @param uri     * @return     */    public static String trimURI(String uri) {        String trimmed = uri.substring(1);        int splashIndex = trimmed.indexOf('/');        return trimmed.substring(splashIndex);    }}

Execution result:

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.