许久不更新博客了。最近在做项目时遇到了一个需要扫描某个包中的某个接口的实现类的需求,在网上搜了一下,发现了一些还不错的实现,但是有句话说得好:“不要重复发明轮子。”像这样的需求肯定是有很多现成的解决方案的。在github和stackoverflow上找了之后发现Reflections库可以完美地实现上述需求,现分享给大家。

Reflections库的依赖:

Gradle:

compile group: 'org.reflections', name: 'reflections', version: '0.9.11'
Maven:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.11</version>
</dependency>

使用起来非常简单:

    @Test
    public void testReflections() {
        Reflections reflections = new Reflections("org.fhp.test.entity");
        Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class);

        for(Class clazz : classes) {
            //logger.info(clazz.getName());
            System.out.println("Found: " + clazz.getName());
        }
    }


假如想扫描整个工程的类,直接new一个不带参数的Reflections就好。值得一提的是,这东西在扫描的时候,连依赖的jar包都不放过。以Spring框架的BeanFactory为例:

import org.springframework.beans.factory.BeanFactory;
    @Test
    public void testReflections() {
        Reflections reflections = new Reflections();
        Set<Class<? extends BeanFactory>> classes = reflections.getSubTypesOf(BeanFactory.class);

        for(Class clazz : classes) {
            //logger.info(clazz.getName());
            System.out.println("Found: " + clazz.getName());
        }
    }


另一个常用的场景是扫描包含指定注解的类。reflections对象中同样包含这一方法,代码如下:

import org.springframework.stereotype.Service;

    @Test
    public void testReflections() {
        Reflections reflections = new Reflections();
        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Service.class);

        for(Class clazz : classes) {
            //logger.info(clazz.getName());
            System.out.println("Found: " + clazz.getName());
        }
    }

Reflections还有很多类似的反射类操作(如扫描方法、扫描参数等),可以说是应有尽有了。有兴趣的小伙伴们可以参考Reflection库的源码或者官方文档,这里就不详述了。

参考地址:https://github.com/ronmamo/reflections






Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐