注意此处,如果要通过接口反射字类的话,一定会去获取某个文件夹中的类来获取。
此时要注意了,如果在没有打包之前是可以获取到的,但是如果日后,要查询的文件夹是在jar包中则就获取不到了。因此此处代码就是我写的即可以获取本地,也可以获取jar中的文件夹。
ClassUtils类:
package cn.teddy.sp.common.utils;
import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.JarURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile;
import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service;
import cn.teddy.sp.common.constant.partner.BaseConstantInterface; /** * 反射获取类信息utils * @author xiaoyuhan * */ public class ClassUtils { /** * 测试获取本地或者jar中,给一个接口,返回这个接口的所有实现类(要求接口和实现类必须在一个包中) * * @param args */ public static void main(String[] args) { List for (String string : s) { System.out.println(string); } }
/** * 给一个接口,返回这个接口的所有实现类 */
public static List List // 如果不是一个接口,则不做处理 if (c.isInterface()) { String packageName = c.getPackage().getName();// 获得当前包名 // System.out.println(packageName); try { List for (int i = 0; i < allClass.size(); i++) { /** * 判定此 Class 对象所表示的类或接口与指定的 Class 参数cls所表示的类或接口是否相同, 或是否是其超类或(超)接口,如果是则返回 * true,否则返回 false。 */ if (c.isAssignableFrom(allClass.get(i))) { if (!c.equals(allClass.get(i))) {// 本身加不进去 Class clazz = allClass.get(i); // 如果类被@Deprecated修饰了,就不添加了 if (clazz.getAnnotation(Deprecated.class) != null) { continue; } String cs = allClass.get(i).toString(); returnClassList.add(cs.substring(cs.indexOf("class ") + 6)); } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return returnClassList; }
/** * 获取本地包中或者jar包中的,某个包中的所有类名 * * @param pkgName * 本地包中或者jar包中的包名称,注意是包名称 * @param isRecursive * ture 外加获取包中子包中的类 false 不获取包中子包的类 * @param annotation * 类上边加的注解 * @return */ public static List Class extends Annotation> annotation) { List ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { // 按文件的形式去查找 String strFile = pkgName.replaceAll("\\.", "/"); Enumeration while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String protocol = url.getProtocol(); String pkgPath = url.getPath(); // System.out.println("protocol:" + protocol +" path:" + pkgPath); if ("file".equals(protocol)) { // 本地自己可见的代码 findClassName(classList, pkgName, pkgPath, isRecursive, annotation); } else if ("jar".equals(protocol)) { // 引用第三方jar的代码 findClassName(classList, pkgName, url, isRecursive, annotation); } } } } catch (IOException e) { e.printStackTrace(); }
return classList; }
public static void findClassName(List Class extends Annotation> annotation) { if (clazzList == null) { return; } File[] files = filterClassFiles(pkgPath);// 过滤出.class文件及文件夹 // System.out.println("files:" +((files == null)?"null" : "length=" + // files.length)); if (files != null) { for (File f : files) { String fileName = f.getName(); if (f.isFile()) { // .class 文件的情况 String clazzName = getClassName(pkgName, fileName); addClassName(clazzList, clazzName, annotation); } else { // 文件夹的情况 if (isRecursive) { // 需要继续查找该文件夹/包名下的类 String subPkgName = pkgName + "." + fileName; String subPkgPath = pkgPath + "/" + fileName; findClassName(clazzList, subPkgName, subPkgPath, true, annotation); } } } } }
/** * 第三方Jar类库的引用。 * * @throws IOException */ public static void findClassName(List Class extends Annotation> annotation) throws IOException { JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); JarFile jarFile = jarURLConnection.getJarFile(); // System.out.println("jarFile:" + jarFile.getName()); Enumeration while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); // 类似:sun/security/internal/interfaces/TlsMasterSecret.class String clazzName = jarEntryName.replace("/", "."); int endIndex = clazzName.lastIndexOf("."); String prefix = null; if (endIndex > 0) { String prefix_name = clazzName.substring(0, endIndex); endIndex = prefix_name.lastIndexOf("."); if (endIndex > 0) { prefix = prefix_name.substring(0, endIndex); } } if (prefix != null && jarEntryName.endsWith(".class")) { // System.out.println("prefix:" + prefix +" pkgName:" + pkgName); if (prefix.equals(pkgName)) { // System.out.println("jar entryName:" + jarEntryName); addClassName(clazzList, clazzName, annotation); } else if (isRecursive && prefix.startsWith(pkgName)) { // 遍历子包名:子类 // System.out.println("jar entryName:" + jarEntryName +" isRecursive:" + // isRecursive); addClassName(clazzList, clazzName, annotation); } } } }
private static File[] filterClassFiles(String pkgPath) { if (pkgPath == null) { return null; } // 接收 .class 文件 或 类文件夹 return new File(pkgPath).listFiles(new FileFilter() { @Override public boolean accept(File file) { return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory(); } }); }
private static String getClassName(String pkgName, String fileName) { int endIndex = fileName.lastIndexOf("."); String clazz = null; if (endIndex >= 0) { clazz = fileName.substring(0, endIndex); } String clazzName = null; if (clazz != null) { clazzName = pkgName + "." + clazz; } return clazzName; }
private static void addClassName(List Class extends Annotation> annotation) { if (clazzList != null && clazzName != null) { Class> clazz = null; try { if (clazzName.endsWith(".class")) { clazzName = clazzName.substring(0, clazzName.indexOf(".class")); } clazz = Class.forName(clazzName); } catch (ClassNotFoundException e) { e.printStackTrace(); } // System.out.println("isAnnotation=" + clazz.isAnnotation() +" author:" + // clazz.isAnnotationPresent(author.class)); if (clazz != null) { if (annotation == null) { clazzList.add(clazz); // System.out.println("add:" + clazz); } else if (clazz.isAnnotationPresent(annotation)) { clazzList.add(clazz); // System.out.println("add annotation:" + clazz); } } } }
/** * 通过类路径和方法名称,获取某个类的,无参方法返回值(String) * * @param methordName 方法名称 * @param classPathName 类路径 * @return */ public static String getMethordResult(String classPathName, String methordName) { Class clazz = null; Object obj = null; Method m3; try { clazz = Class.forName(classPathName); obj = clazz.newInstance(); m3 = clazz.getMethod(methordName); return (String) m3.invoke(obj); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } }
/** * 通过类路径和方法名称和参数,获取某个类的,带参方法返回值(Object) * * @param methordName 方法名称 * @param classPathName 类路径 * @return */ public static Object getMethordResult(String classPathName, String methordName, String... strings) { Class clazz = null; Object obj = null; Method m3; try { clazz = Class.forName(classPathName); obj = clazz.newInstance(); Class [] cs = new Class[strings.length]; for(int i =0;i cs[i]=String.class; } m3 = clazz.getMethod(methordName, cs); return m3.invoke(obj, strings); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } /** * 获取指定jar中的所有类,所有方法,所有属性 测试 * 使用getJarName("/Library/Java/JavaVirtualMachines/apache-tomcat-8.5.30/webapps/ROOT/WEB-INF/lib/sp-common-1.0-SNAPSHOT.jar"); * * @param jarFile jar包的路径 * @throws Exception */ public static void getJarName(String jarFile) throws Exception { try { // 通过将给定路径名字符串转换为抽象路径名来创建一个新File实例 File f = new File(jarFile); URL url1 = f.toURI().toURL(); URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url1 }, Thread.currentThread().getContextClassLoader()); // 通过jarFile和JarEntry得到所有的类 JarFile jar = new JarFile(jarFile); // 返回zip文件条目的枚举 Enumeration JarEntry entry; // 测试此枚举是否包含更多的元素 while (enumFiles.hasMoreElements()) { entry = (JarEntry) enumFiles.nextElement(); if (entry.getName().indexOf("META-INF") < 0) { String classFullName = entry.getName(); if (!classFullName.endsWith(".class")) { classFullName = classFullName.substring(0, classFullName.length() - 1); } else { // 去掉后缀.class String className = classFullName.substring(0, classFullName.length() - 6).replace("/", "."); Class> myclass = myClassLoader.loadClass(className); // 打印类名 // System.out.println("*****************************"); System.out.println("全类名:" + className); // 得到类中包含的属性 Method[] methods = myclass.getMethods(); for (Method method : methods) { String methodName = method.getName(); System.out.println("方法名称:" + methodName); Class>[] parameterTypes = method.getParameterTypes(); for (Class> clas : parameterTypes) { // String parameterName = clas.getName(); String parameterName = clas.getSimpleName(); System.out.println("参数类型:" + parameterName); } System.out.println("=========================="); } } } } } catch (IOException e) { e.printStackTrace(); } } } |