首页 新闻 会员 周边

springmvc运行时反射获取webapps下某项目中的所有class文件的注解

0
[待解决问题]

由于业务需要,在webapps下有两个项目A和B,A项目要获取B项目中所有controller的注解。可是同样的代码在普通的main函数执行可以获取到,但是部署到tomcat中就获取不到,感觉和classloader有关系,但是又不大懂,有没有高人指导?

 

这是反射代码

public class Recursion {

    /**
     * 递归获取指定文件或者文件夹下的指定文件
     *
     * @param path
     * @param filePaths
     * @param fileType
     */

    public static void searchFiles(String path, List<String> filePaths, String fileType) {
        File file = new File(path);
        if (file.isFile()) {
            filePaths.add(path);
            return;
        }
        File[] files = file.listFiles();
        if (files != null) {
            for (File itemFile : files) {
                if (itemFile.isFile() && itemFile.getName().endsWith(fileType)) {
                    filePaths.add(itemFile.getAbsolutePath());
                } else if (itemFile.isDirectory()) {
                    searchFiles(itemFile.getAbsolutePath(), filePaths, fileType);
                }
            }
        }
    }


    /**
     * 返回包名和class文件路径的字典集合
     *
     * @param path
     * @return
     */

    public static ConcurrentHashMap<String, String> getClasses(String path) {
        List<String> filePaths = new ArrayList<>();
        searchFiles(path, filePaths, ".class");
        ConcurrentHashMap<String, String> classs = new ConcurrentHashMap<>();
        for (String filePath : filePaths) {
            int classes = filePath.indexOf("classes");
            String packageName = filePath.substring(classes + 8, filePath.length());
            packageName = packageName.replaceAll("\\\\", ".");
            packageName = packageName.replaceAll(".class", "");
            classs.put(packageName, filePath);
        }
        return classs;
    }
}
public class ClassLoaderUtil extends ClassLoader {
    private byte[] results;

    public ClassLoaderUtil(String classPathName) {
        results = loadClassFile(classPathName);
    }


    /**
     * @param packageName 包名
     */
    public void getAnnotations(String packageName) {
        try {
            Class<?> clazz = this.loadClass(packageName);
            Object object = clazz.newInstance();
            Annotation[] annotations = object.getClass().getAnnotations();
            System.out.println(object.getClass().getName());
            System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            for (Annotation annotation : annotations) {
                System.out.println(annotation.toString());
            }
            System.out.println("");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 把class文件转成字节码
     *
     * @param classPath
     * @return
     */
    private byte[] loadClassFile(String classPath) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            FileInputStream fi = new FileInputStream(classPath);
            BufferedInputStream bis = new BufferedInputStream(fi);
            byte[] data = new byte[1024 * 256];
            int ch = 0;
            while ((ch = bis.read(data, 0, data.length)) != -1) {
                bos.write(data, 0, ch);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return bos.toByteArray();

    }

    @Override
    protected Class<?> loadClass(String arg0, boolean arg1) {
        Class<?> clazz = findLoadedClass(arg0);
        if (clazz == null) {
            if (getParent() != null) {
                try {
                    //这里我们要用父加载器加载如果加载不成功会抛异常
                    clazz = getParent().loadClass(arg0);
                } catch (Exception e) {
                }
            }
            if (clazz == null) {
                clazz = defineClass(arg0, results, 0, results.length);
            }
        }
        return clazz;
    }
}

这是普通类测试代码

public class test {
    public static void main(String[] args) {
        String webBaseRealPath = "D:\\myself\\apache-tomcat-8.5.28\\webapps\\http\\WEB-INF\\classes\\com\\sac\\web\\controller";
        ConcurrentHashMap<String, String> classes = Recursion.getClasses(webBaseRealPath);
        classes.forEach((k, v) -> {
            ClassLoaderUtil myClassLoader = new ClassLoaderUtil(v);
            myClassLoader.getAnnotations(k);
        });
    }
}

是可以获取到注解的

但是放在控制器下,为什么就不行呢?

 @RequiresRoles({"dev"})
    @ApiOperation(notes = "GET", httpMethod = "GET", value = "获取系统全部资源列表")
    @GetMapping(value = "resources/total")
    public ResponseEntity getAll(HttpServletRequest servletRequest) throws ClassNotFoundException {
        String webBaseRealPath = servletRequest.getServletContext().getRealPath("");
        String webBusinessRelativePath = ConfigurationProvider.config.getWebCore().getPublishPath().getBussinessApiRelativePath();
        String webBaseRelativePath = ConfigurationProvider.config.getWebCore().getPublishPath().getApiRelativePath();
        String webBusinessRealPath = webBaseRealPath.replace(webBaseRelativePath, webBusinessRelativePath);
        //test
        webBaseRealPath = "D:\\myself\\apache-tomcat-8.5.28\\webapps\\http\\WEB-INF\\classes\\com\\sac\\web\\controller";
        ConcurrentHashMap<String, String> classes = Recursion.getClasses(webBaseRealPath);
        classes.clear();
        classes.put("com.sac.web.controller.BaseController",
                "D:\\myself\\apache-tomcat-8.5.28\\webapps\\http\\WEB-INF\\classes\\com\\sac\\web\\controller\\BaseController.class");
        classes.forEach((k, v) -> {
            ClassLoaderUtil myClassLoader = new ClassLoaderUtil(v);
            myClassLoader.getAnnotations(k);
        });
        //Class<?> aClass = Class.forName("com.sac.web.controller.OrganizationController");
        resourceService.getAllSystemResources(webBaseRealPath);
        return null;
    }
小艾eason的主页 小艾eason | 初学一级 | 园豆:9
提问于:2018-06-22 09:33
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册