写简单的mvc框架实例讲解(2)

这个方法接收两个参数,一个是包名packageName,一个是一个空的Set(不是null),在方法执行完毕会将包下的所有class填充进Set中。这里主要是判断了一下这个包中有那些类型的文件,并根据文件类型分别处理。

注意:如果是jar文件的类型,获取到的filePath是这样的:

file:/home/hjx/idea-IU/lib/idea_rt.jar!/com

需要去掉头和尾,然后就可以吃了,鸡肉味!嘎嘣脆~~ 处理之后的是这个样子:

/home/hjx/idea-IU/lib/idea_rt.jar

下面是方法代码:

/** * 从给定的报名中找出所有的class * * @param packageName * @param classes */ @SneakyThrows({IOException.class}) public static void getClassByPackage(String packageName, Set<Class> classes) { Assert.notNull(classes); String packagePath = packageName.replace(DOT, SLASH); Enumeration<URL> resources = ClassUtils.getClassLoader().getResources(packagePath); while (resources.hasMoreElements()) { URL url = resources.nextElement(); //文件类型 String protocol = url.getProtocol(); String filePath = URLDecoder.decode(url.getFile(), CHARSET_UTF_8); if (TYPE_FILE.equals(protocol)) { getClassByFilePath(packageName, filePath, classes); } if (TYPE_JAR.equals(protocol)) { //截取文件的路径 filePath = filePath.substring(filePath.indexOf(":") + 1, filePath.indexOf("!")); getClassByJarPath(packageName, filePath, classes); } } }

2:void getClassByFilePath(String packageName, String filePath, Set

将文件夹中的全部符合条件的class找到,用到递归。需要将class文件的绝对路径截取成class的全限定名,代码这个样子:

/** * 在文件夹中递归找出该文件夹中在package中的class * * @param packageName * @param filePath * @param classes */ static void getClassByFilePath( String packageName, String filePath, Set<Class> classes ) { File targetFile = new File(filePath); if (!targetFile.exists()) { return; } if (targetFile.isDirectory()) { File[] files = targetFile.listFiles(); for (File file : files) { String path = file.getPath(); getClassByFilePath(packageName, path, classes); } } else { //如果是一个class文件 boolean trueClass = filePath.endsWith(CLASS_MARK); if (trueClass) { //提取完整的类名 filePath = filePath.replace(SLASH, DOT); int i = filePath.indexOf(packageName); String className = filePath.substring(i, filePath.length() - 6); //不是一个内部类 boolean notInnerClass = className.indexOf("$") == -1; if (notInnerClass) { //根据类名加载class对象 Class aClass = ClassUtils.forName(className); if (aClass != null) { classes.add(aClass); } } } } }

3:void getClassByJarPath(String packageName, String filePath, Set

将jar文件中的全部符合条件的class找到。没啥说的,下面是代码:

/** * 在jar文件中找出该文件夹中在package中的class * * @param packageName * @param filePath * @param classes */ @SneakyThrows({IOException.class}) static void getClassByJarPath( String packageName, String filePath, Set<Class> classes ) { JarFile jarFile = new URLJarFile(new File(filePath)); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); String jarEntryName = jarEntry.getName().replace(SLASH, DOT); //在package下的class boolean trueClass = jarEntryName.endsWith(CLASS_MARK) && jarEntryName.startsWith(packageName); //不是一个内部类 boolean notInnerClass = jarEntryName.indexOf("$") == -1; if (trueClass && notInnerClass) { String className = jarEntryName.substring(0, jarEntryName.length() - 6); System.out.println(className); //根据类名加载class对象 Class aClass = ClassUtils.forName(className); if (aClass != null) { classes.add(aClass); } } } }

这样,获取包名下的class就写完了~

修改UrlMethodMappingFactory

这里新添加一个方法:

List,将扫描包之后获取到的Class对象作为参数,返回一个UrlMethodMapping集合就好了。代码如下:

/** * 通过解析Class 获取映射 * * @param aClass * @return */ public List<UrlMethodMapping> getUrlMethodMappingListByClass(Class<Request> aClass) { List<UrlMethodMapping> mappings = new ArrayList<>(); Request request = aClass.getDeclaredAnnotation(Request.class); if (request == null) { return mappings; } String basePath = request.value(); for (Method classMethod : aClass.getDeclaredMethods()) { UrlMethodMapping urlMethodMapping = getUrlMethodMappingListByMethod(classMethod); if (urlMethodMapping == null) { continue; } //将添加在class上的Request中的path作为基础路径 String url = UrlUtils.makeUrl(basePath + "https://www.jb51.net/" + urlMethodMapping.getUrl()); urlMethodMapping.setUrl(url); mappings.add(urlMethodMapping); } return mappings; } /** * 通过解析Method 获取映射 * 注解Request不存在时跳出 * * @param method * @return */ private UrlMethodMapping getUrlMethodMappingListByMethod(Method method) { Request request = method.getDeclaredAnnotation(Request.class); if (request == null) { return null; } Class<?> declaringClass = method.getDeclaringClass(); String path = request.value(); for (char c : path.toCharArray()) { Assert.isTrue(c != ' ', declaringClass + "." + method.getName() + "请求路径异常:" + path + " !"); } return getUrlMethodMapping( path, request.type(), declaringClass, method, method.getParameterTypes() ); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsdws.html