java小工具——包扫描

在模拟实现Spring时我们需要知道哪些类上有Component注解从而生成其对象放如容器中,如何知道类上有Component注解?这里用到了包扫描。包扫描在扫描到类之后不仅可以判断类上是否有注解还可以进行其他操作(由用户定义实现),在这片文章中我们来说一下包扫描

public abstract class PackageScanner {
	
	public PackageScanner() {
	}
	
	public void scanPackage(String packageName) {
		//将包名转换为目录
		String pathName = packageName.replace('.', '/');
		//获取当前目录的URL
		URL url = Thread.currentThread().getContextClassLoader().getResource(pathName);
		//用url来判断要扫描的是普通包还是jar包
		if(url.getProtocol().equals("file")) {
			try {
				//生成普通包的最后一级目录
				File curFile = new File(url.toURI());
				//对普通包进行扫描
				dealPackage(curFile, packageName);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			}
		}else if(url.getProtocol().equals("jar")) {
			//对jar包进行扫描
			dealJar(url);
		}

	}
	//普通包扫描方法
	private void dealPackage(File cur, String packageName) {
		//获取最后一级目录的文件
		File[] files = cur.listFiles();
		//对获取的文件进行处理
		for (File file : files) {
			//判断是否是文件
			if (file.isFile()) {
				//如果文件名不以.class结尾则不予处理
				//否则调用dealClass(klass)方法对扫描到的类进行处理
				String fileName = file.getName();
				if (!fileName.endsWith(".class")) {
					continue;
				}
				fileName = fileName.replace(".class", "");
				String className = packageName + "." + fileName;
				try {
					Class<?> klass = Class.forName(className);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			} else {
				//如果不是文件(目录),则递归调用普通包扫描方法
				dealPackage(file, packageName + "." + file.getName());
			}
		}
	}
	
	private void dealJar(URL url) {
		try {
			//建立了访问 jar包URL的连接
			JarURLConnection connection = (JarURLConnection) url.openConnection();
			//通过连接得到JarFile
			JarFile jarFile = connection.getJarFile();
			//获取该JarFile目录下所有项目
			Enumeration<JarEntry> entryList = jarFile.entries();
			//遍历得到的jarEntries 
			while (entryList.hasMoreElements()) {
				JarEntry jarEntry = entryList.nextElement();
				//如果是目录或者不是class文件,不予处理
				if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class")) {
					continue;
				}
				//调用dealClass(klass)方法对扫描到的类进行处理
				String className = jarEntry.getName();
				className = className.replace(".class", "");
				className = className.replace('/', '.');
				try {
					Class<?> klass = Class.forName(className);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//扫描到类之后的具体操作,由用户实现
	public abstract void dealClass(Class<?> klass);
		
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值