복붙노트

[SPRING] 안드로이드에서 스프링과 같은 패키지 스캐닝 구현하기

SPRING

안드로이드에서 스프링과 같은 패키지 스캐닝 구현하기

나는 개발중인 안드로이드 프레임 워크에서 Spring의 컴포넌트 스캔과 비슷한 패키지 스캔 기능을 구현하려고 시도하고있다. 기본적으로 기본 패키지를 지정할 수 있습니다. com.foo.bar를 사용하고 특정 주석이있는 모든 Class 인스턴스를 검색합니다. 나는 자동 스캐닝의 목적에 어긋나지 않도록 모든 구성 요소를 프레임 워크에 등록하고 싶지 않습니다.

필자의 연구에 따르면 Java에서는 리플렉션을 사용하여 패키지 이름이 지정된 리소스를 검색 할 수 없다고합니다. 그러나 간단히 Reflections 프레임 워크를 살펴 봤는데 안드로이드 호환 장치가 있는지 궁금합니다. 그렇지 않다면, 아마도 내가하고 싶은 것을 성취하기위한 약간 덜 분명한 방법이있을 것입니다.

스프링 소스를 조금 쳐다 보았지만, 어떻게 달성했는지는 알 수 없었지만, 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;
}

해결법

  1. ==============================

    1.나는 Joop Eggen의 의견을 공유하고 그의 접근법을 좋은 것으로 생각한다. Android에서는 오래 지속되는 애플리케이션 시작으로 이어지는 일반적인 웹 앱 기능을 피하려고합니다. 리플렉션 또는 패키지 검색을 사용하지 않습니다.

    나는 Joop Eggen의 의견을 공유하고 그의 접근법을 좋은 것으로 생각한다. Android에서는 오래 지속되는 애플리케이션 시작으로 이어지는 일반적인 웹 앱 기능을 피하려고합니다. 리플렉션 또는 패키지 검색을 사용하지 않습니다.

    그러나 만약 당신이 원한다면 ... 나는 그것을 정확하게 이해한다면 당신은 수업을위한 주석을 원한다. 어노테이션을 사용하는 대신 마커 인터페이스를 사용할 수도 있습니다 (더 많은 가능성을 갖기 위해서).

    AndroidAnnotations가 작동하는 방식을 선호합니다 (AndroidAnnotations의 통합이 바람직한 방법 일 수 있습니다). 표준 Java Annotation Processing Tool을 사용하여 소스 코드를 생성하는 추가 컴파일 단계를 자동으로 추가합니다. 따라서 런타임 검색 대신 컴파일 타임에 생성 된 주석을 기반으로 코드를 실행합니다.

    Bean / EBean 주석은 단일 클래스만으로 작동 할 수 있다고 생각합니다. https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes

    스캔 기능을 사용할 수 없습니다.이 스레드보기

  2. ==============================

    2.나는 런타임에 모든 하위 클래스를 찾고 싶었다. 그래서 나는 안드로이드 클래스 스캐닝을 찾고있었습니다. 이것이 내가 웹에서 수집 한 마지막 코드입니다. 당신은 아이디어를 얻을 것이다.

    나는 런타임에 모든 하위 클래스를 찾고 싶었다. 그래서 나는 안드로이드 클래스 스캐닝을 찾고있었습니다. 이것이 내가 웹에서 수집 한 마지막 코드입니다. 당신은 아이디어를 얻을 것이다.

    public static void findSubClasses(Context context, Class parent) {
        ApplicationInfo ai = context.getApplicationInfo();
        String classPath = ai.sourceDir;
        DexFile dex = null;
        try {
            dex = new DexFile(classPath);
            Enumeration<String> apkClassNames = dex.entries();
            while (apkClassNames.hasMoreElements()) {
                String className = apkClassNames.nextElement();
                try {
                    Class c = context.getClassLoader().loadClass(className);
                    if (parent.isAssignableFrom(c)) {
                        android.util.Log.i("nora", className);
                    }
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //              android.util.Log.i("nora", className);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                dex.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
  3. ==============================

    3.Vogar의 ClassPathScanner를 살펴보십시오. 이 클래스를 사용하여 클래스 경로에서 테스트 케이스를 찾습니다.

    Vogar의 ClassPathScanner를 살펴보십시오. 이 클래스를 사용하여 클래스 경로에서 테스트 케이스를 찾습니다.

  4. ==============================

    4.편집하다:

    편집하다:

  5. ==============================

    5.자바 빌드 과정에서 클래스 경로 스캐닝을 통합하여 주입 데이터 / 코드를 생성합니다. 이것은 Dalvik에게도 이식 될 수 있습니다. 동적 검색보다 훨씬 효율적입니다.

    자바 빌드 과정에서 클래스 경로 스캐닝을 통합하여 주입 데이터 / 코드를 생성합니다. 이것은 Dalvik에게도 이식 될 수 있습니다. 동적 검색보다 훨씬 효율적입니다.

  6. from https://stackoverflow.com/questions/11421085/implementing-spring-like-package-scanning-in-android by cc-by-sa and MIT license