java 包扫描 —————— 开开开山怪

包扫描

1.包扫描过程

包扫描事实上就是通过包名称来扫描到该包下该包下的文件夹下的所有class文件,为我们需要处理的.class文件提前提供一个获取.class文件的一个手段。
只需要提供该包的名称便可以扫描到包下所有的.class文件。而事实上包相当于文件夹。
那我们需要做的就是对提供的包名称进行处理,从而做一个工具可以自动扫描到该包下的所有类。

First

通过包名称得到URL,再根据URL判断该包属于普通包还是jar

Second

若是普通包,我们需要去做判断,分两种情况
1.该包下直接就是子文件(.class文件)
2.该包下存在子文件夹,那么我们又得将这个文件夹看做是普通包对待,接着判断属于哪两种情况。

其实在这一步采用的是递归的方法,之前对递归也不是很熟练,不知道在什么时候用敌对,对于这一步来是个很好的例子,一个很好的方法理解 ==递归 就是只考虑本层需要干的事情。

对于普通包来说我们最终的目的是要扫描出clas是文件,但此时阻挡我们的是给的包名称可能包含的不是class文件而是一个或多个文件夹,这些文件夹中可能含有class文件,就是一环套一环的感觉。

那我给一个方法就是dealDirectory( String rootName, File curFile).那这个方法来处理普通包,可以看做是我们本层所要分析及实现的,那本层我们需要干的事情就是判断是上述说的两种情况,因为对一个包名称来说无非两种情况,dealDirectory(String rootName, File curFile)需要干的事情就是做两种判断,当curFile文件下是文件夹是调用自己(也就是dealDirectory(),因为此时的文件夹又可以看做时候一个普通包),当curFile文件下是class文件时,直接当做文件处理。

Third

若是jar包,只有判断出是class文件我们当做文件处理,其他的不做处理

2.代码


public abstract class PackageScanner {
	public PackageScanner() {
	 }
	public abstract void dealClass(Class<?> className);
	private void dealFile(String rootName, File curFile) {
	     String fileName = curFile.getName();
		      
	     if (fileName.endsWith(".class")) {
		fileName = fileName.replace(".class", ""); 
		try {    
		   Class<?> klass = Class.forName(rootName + "." + fileName);
		   dealClass(klass);
	        } catch (Exception e) {
		   e.printStackTrace();
	        }
	      }  
	}
	private void dealDirectory(String rootName, File curFile) {
	 //得到当前curFile中是否含有子文件夹或者文件列表
	      File[] fileList = curFile.listFiles();
		 
	      for(File file : fileList) {	  
		 if (file.isDirectory()) {  
		   dealDirectory("rootName" + file.getName(), file);
		  } else if(file.isFile()){   
		   dealFile(rootName, file);   
		  }
	      }
		 
	}
	private void dealJarPackage(URL url) {
	      try {
		  JarURLConnection connection = (JarURLConnection) url.openConnection();
		  JarFile jarFile = connection.getJarFile();
		  Enumeration<JarEntry> jarEntries = jarFile.entries();
		  while (jarEntries.hasMoreElements()) {
		     JarEntry jar = jarEntries.nextElement();
		   
		     if(jar.isDirectory() || !jar.getName().endsWith(".class")) {
		         continue;
		     }   
		     String jarName = jar.getName(); 
		     jarName = jarName.replace(".class", "");
		     jarName = jarName.replace("/", ".");
		   
		     try {
		        Class<?> klass = Class.forName(jarName);
		        dealClass(klass);
		     } catch (ClassNotFoundException e) {
		         e.printStackTrace();
		     }
		  }
	      } catch (IOException e) {
		  e.printStackTrace();
	      }
	}
	public void scannPackege(String  packegeName) {
	    String rootName = packegeName; 
	    //可以通过将XX.xx.xx转化为xx/xx/xx/
	    //转化为xx/xx/xx/的目的地为了准确得到统一定位url,再通过url判断是file还是jar
	 
	    packegeName = packegeName.replace(".", "/");
	    URL url = Thread.currentThread().getContextClassLoader().getResource(packegeName); 
	    if (url.getProtocol().equals("file")) {
	      //处理普通包
	       try {
	          URI uri = url.toURI();
	          File root = new File(uri); 
	         //root是得到当前packegeName的绝对路径
	          dealDirectory(rootName, root);  
	        } catch (Exception e) {
	            e.printStackTrace();
	        } 
             } else {
	         //处理jar包
	       dealJarPackage(url);
	     } 
	}
}
	
	
	
	```
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值