请教大家一个问题,如下:
我们知道,Spring中可以配置一个属性base-package,配置了这个属性以后,所有的在这个包或者子包下的类都将会被扫描,如果这些类配置了某些annotation,则将会被特别处理。
我的问题是spring是怎么拿到这些类的class的? 举个例子:类的层次结构如下:
    com.test.action中有一个ListAction
    com.test.service中有一个ListService
我配置了一个base-package为com.test那么我在程序中怎么知道有一个ListAction和ListService类?

解决方案 »

  1.   

    在相应的类上加上注解,如服务类,在类上加上@Services("XXX")
      

  2.   

    说直白一点,给你一个包名com.test,你将这个包及其子包下的类全部找出来,该怎么做?
      

  3.   

    String pack = "com.test";
    pack ="/"+pack.replace(".", "/");
    String packPath = System.getProperty("user.dir")+ "/src"+ pack;
    这样可以先得到你的包所在目录的全路径,然后再写方法去遍历得到下面的所有类就可以啦
      

  4.   

    如果是需要拿到class文件,则可以
    File dir = new File(getClass().getResource(pack).getFile());

    File[] fs = dir.listFiles();
      

  5.   


    在WEB中也可以这样吗?  
      

  6.   


    你的意思是 Spring 怎么做的么?可以告诉你,Spring 是采用 ASM 工具分析字节码,从中获取的。使用 ASM 的话可以不用加载类。
      

  7.   


    我没有想那么高级,我的目的只是想根据一个包名,例如com.test,那么我就能够在程序中扫描出这个包名下的所有类,楼上有一个人说的根据路径其实也可以,但是在WEB环境中可以吗?
      

  8.   

    包含 com.test 子包下的类么?
      

  9.   

    只需要找到字节码文件就可以了,关键是怎么根据这个包名信息来找到字节码文件,找到了也可以不用加载类啊,通过classloader的defineclass方法以流的形式读入class文件,也不用加载类啊
      

  10.   

    参考代码,jar 的部分没处理好,你自己完善一下吧。import java.io.File;
    import java.io.IOException;
    import java.net.JarURLConnection;
    import java.net.URISyntaxException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.Enumeration;
    import java.util.jar.JarEntry;public class Main {    public static void main(String[] args) throws IOException, URISyntaxException, ClassNotFoundException {
            ClassLoader classloader = Thread.currentThread().getContextClassLoader();
            String baseName = baseName(classloader);
            Enumeration<URL> em = classloader.getResources("com/test");
            while(em.hasMoreElements()) {
                URL url = em.nextElement();
                
                // jar 包中的
                URLConnection connection = url.openConnection();
                if("jar".equals(url.getProtocol()) && connection instanceof JarURLConnection) {
                    JarURLConnection jar = (JarURLConnection)connection;
                    JarEntry entry = jar.getJarEntry();
                    System.out.println(entry);
                    for(Enumeration<JarEntry> e = jar.getJarFile().entries(); e.hasMoreElements(); ) {
                        System.out.println(e.nextElement());
                    }
                    continue;
                }
                
                // 源代码中的
                File file = new File(url.toURI());
                File[] files = file.listFiles();
                for(File f : files) {
                    scan(f, baseName, classloader);
                }
            }
        }    private static String baseName(ClassLoader classloader) throws URISyntaxException {
            return new File(classloader.getResource("").toURI()).getAbsolutePath();
        }    private static void scan(File dir, String baseName, ClassLoader classloader) throws ClassNotFoundException {
            if(dir.isDirectory()) {
                File[] files = dir.listFiles();
                for(File file : files) {
                    scan(file, baseName, classloader);
                }
                return;
            }
            scan2(dir, baseName, classloader);
        }    private static void scan2(File dir, String baseName, ClassLoader classloader) throws ClassNotFoundException {
            String className = dir.getAbsolutePath().substring(baseName.length() + 1);
            int dot = className.indexOf('.');
            if(dot > -1) {
                className = className.substring(0, dot);
            }
            if(className.indexOf('\\') > -1) {
                className = className.replace('\\', '.');
            }
            if(className.indexOf('/') > -1) {
                className = className.replace('/', '.');
            }
            Class<?> clazz = classloader.loadClass(className);
            System.out.println(clazz.getName());
        }    protected static String determineRootDir(String location) {
            int prefixEnd = location.indexOf(":") + 1;
            int rootDirEnd = location.length();
            while (rootDirEnd > prefixEnd && true) {
                rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1;
            }
            if (rootDirEnd == 0) {
                rootDirEnd = prefixEnd;
            }
            return location.substring(0, rootDirEnd);
        }
    }