java – 在Android中实现类似Spring的包扫描

我正在尝试为我正在开发的Android框架实现类似于Spring的组件扫描的包扫描功能.基本上,我希望能够指定一个基本包,例如com.foo.bar并检索具有特定注释的所有Class实例.我不想用我的框架注册每个组件,因为这会破坏自动扫描的目的.

根据我的研究,似乎Java无法使用反射检索包名称的资源.但是,我简要介绍了Reflections framework,我想知道是否有与Android兼容的等价物.如果没有,或许有一种不那么明显的方式来完成我想做的事情.

我查看了Spring源代码,看看他们是如何实现这一目标的,但我不认为他们正在做什么会在Dalvik运行时内工作.

更新

目前,下面的代码是我能够检索包含特定注释的所有类的最佳代码,但坦率地说,这是一个非常糟糕的解决方案.它对ClassLoader做了一些非常安全的假设,并且它扫描(并加载)所有应用程序类.

public Set<Class<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation) {
    Set<Class<?>> classes = new HashSet<Class<?>>();
    Field dexField = PathClassLoader.class.getDeclaredField("mDexs");
    dexField.setAccessible(true);
    PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader();
    DexFile[] dexs = (DexFile[]) dexField.get(classLoader);
    for (DexFile dex : dexs) {
        Enumeration<String> entries = dex.entries();
        while (entries.hasMoreElements()) {
            String entry = entries.nextElement();
            Class<?> entryClass = dex.loadClass(entry, classLoader);
            if (entryClass != null && entryClass.isAnnotationPresent(annotation)) {
                classes.add(entryClass);
            }
        }
    }
    return classes;
}

解决方法:

我赞同Joop Eggen的观点并发现他的方法很好.在Android中,我尝试避免通常的Web应用程序功能,这会导致应用程序启动持久.我不使用反射或包扫描.

但是如果你想….如果我理解正确你想要一个类的注释.您也可以使用标记界面(仅具有更多可能性),而不是使用注释.

1)看看

>注释:Java custom annotation and dynamic loading
在问题中有一个实现,它只是回答你的问题.
>注释:Scanning Java annotations at runtime
>界面:Find Java classes implementing an interface
>界面:Is something similar to ServiceLoader in Java 1.5?
>界面:How can I get a list of all the implementations of an interface programmatically in Java?
>接口:由于方法很昂贵,ServiceLoader可能是执行时间和舒适度之间的折衷,因为它只加载服务文件中给出的类.另一方面,如果只有具有特定接口的类在您的包中,那么ServiceLoader就不那么快了.

2)AndroidAnnotations

我更喜欢AndroidAnnotations工作的方式(可能是AndroidAnnotations中的集成是更好的方式):它使用标准的Java Annotation Processing Tool自动添加一个生成源代码的额外编译步骤.因此,不是运行时扫描,而是根据编译时生成的注释执行代码.

我认为Bean / EBean注释可以为你工作(只有单个类):https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes

扫描功能不可用,请参阅此thread

3)编写自己的注释处理器

>见APT (Annotation Processing Tool).想法是生成一个静态函数,它返回一个注释类的列表,这样就不需要进行类扫描.
>一个非常好的资源是http://javadude.com/articles/annotations/index.html

上一篇:java – 直接访问静态字段而不是调用静态getter方法,它更快吗?


下一篇:Java反射:实现接口并传递给另一个类