获取包以及jar 包下的类

    xiaoxiao2022-07-03  114

    首先,Java中的getResourceAsStream获取项目下的指定资源有以下几种: 

    一:获取src下的指定资源

    1 通过Class.getResource 来获取。  path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下(即'/'代表src)获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源

    //必须要从根节点进行获取,即以/ 开头 TempMain.class.getResource("/application.yml");

    2 Class.getResourceAsStream 与Class.getResource 一样,只是将获取到的URL 进行了流的处理 

    TempMain.class.getResourceAsStream("/application.yml");

     

    3 Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。

    TempMain.class.getClassLoader().getResourceAsStream("application.yml");

    4 备注:

    如果当前项目里引用里其他的jar 包,并且在相同的路径下存在着相同的文件,那么也会读取到,spring 的starter 就是利用改机制来发现配置类,从而实现自动装配的

    二:获取web项目下的指定资源

        1)、 ServletContext. getResourceAsStream(String path):默认从WebAPP根目录(即:要发布在服务器下的项目的根目录(与src同级的web文件夹下))下取资源,path是否以’/'开头无所谓;

      A)、在web项目的根目录下有myfile.xml文件,则应该使用: getServleContext().getResourceAsStream("myfile.xml");  

    2)、Jsp下的application内置对象就是上面的ServletContext的一种实现

    三 获取指定包下的所有class类

    需要先将包名转化为路径名,比如讲org.apache 转换为 org/apache ,然后通过循环遍历找到该文件下有哪些类,然后在将路径名转化为类名,通过反射即可拿到。 

    或者通过第一步获取到了资源文件 , 然后通过解析资源文件, 获取到对应的ClassName ,然后通过反射来实现 。 (可以使用Spring 中的 ClassReader )

    四 获取jar包里的class文件

    先通过第一种方法获取到对应的jar文件,然后通过 

    1.通过jarFile JarFile jarFile = new JarFile(file); 2 通过 jarInputStream ,Demo里有

    获取到jarFile,接着通过第三部即可

    五 demo

    public class ClassUtil { private static final byte[] JAR_MAGIC = {'P', 'K', 3, 4}; public static void main(String[] args) throws IOException { ClassUtil classUtil = new ClassUtil(); List<Class> classes = classUtil.listClass("com.google"); System.out.println(classes); } public List<Class> listClass(String packageName) throws IOException { List<String> list = listResource(packageName); List<Class> result = new ArrayList<>(); for (String name : list) { name = name.substring(0, name.lastIndexOf(".")).replace("/", "."); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Class<?> aClass = classLoader.loadClass(name); result.add(aClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return result; } public List<String> listResource(String packageName) throws IOException { String path = packageName.replace(".", "/"); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL url = classLoader.getResource(path); URL jarUrl = findJarForResource(url); // 如果是jar包的话 if (jarUrl != null) { return listResources(new JarInputStream(jarUrl.openStream()), path); } InputStream is = url.openStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); List<String> resources = Lists.newArrayList(); String line; while ((line = reader.readLine()) != null) { //如果是类的话 if (line.indexOf(".class") > 0) { resources.add(path + "/" +line); // 是目录的话 }else{ List<String> children = listResource(path + "/" + line); if(children!=null && children.size()>0){ resources.addAll(children); } } } reader.close(); return resources; } private URL findJarForResource(URL url) throws IOException { String jarUrl = url.getPath(); int index = jarUrl.indexOf(".jar"); if (index < 0) { return null; } jarUrl = jarUrl.substring(0, index + 4); URL testUrl = new URL(jarUrl); if (isJar(testUrl)) { return testUrl; } return null; } // 通过文件的魔数来判断是否是jar 文件 private boolean isJar(URL testUrl) throws IOException { InputStream inputStream = testUrl.openStream(); byte[] buffer = new byte[JAR_MAGIC.length]; inputStream.read(buffer, 0, JAR_MAGIC.length); if (Arrays.equals(JAR_MAGIC, buffer)) { return true; } inputStream.close(); return false; } // 通过jar 来获取resourced protected List<String> listResources(JarInputStream jar, String path) throws IOException { //为path 在开头和末尾添加 / if (!path.startsWith("/")) { path = "/" + path; } if (!path.endsWith("/")) { path = path + "/"; } List<String> resources = new ArrayList<>(); for (JarEntry entry; (entry = jar.getNextJarEntry()) != null; ) { if (!entry.isDirectory()) { StringBuilder name = new StringBuilder(entry.getName()); // 进行文件名的统一 if (name.charAt(0) != '/') { name.insert(0, '/'); } if (name.indexOf(path) == 0) { // 去掉开头的斜杠 resources.add(name.substring(1)); } } } return resources; } }

     

    最新回复(0)