2012-08-08 20 views
0

我過去使用過Reflections庫來查詢具有特定註釋的類路徑中的類或從特定類繼承的類。 由於圖書館已經提供了回答這些特定查詢的方法,因此使用Reflections很容易。使用Reflections庫在Java classpath中查詢具有任意屬性的類

例如,下面的代碼說明了如何查詢與SomeAnnotation註解的類從SomeType繼承和類,尋找位於封裝類(從Reflection.java類的文檔所採取的示例)my.package.prefix

Reflections reflections = new Reflections("my.package.prefix"); 
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class); 
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class); 

但是,在我目前的問題中,我需要做的是查詢具有任意屬性集合的類(例如,特定類名+現有註釋+無論什麼組合)。我不知道這些屬性,因爲它們應該由程序員使用我正在開發的庫來定義。

我想,解決方案的一部分就像是要求程序員用布爾方法來定義一個Strategy類,如果該類應該在答案集中或者不是。

例如,程序員應該執行類似的接口:

public interface MyStrategy { 
    public boolean match(Class clazz); 
} 

所以我的問題是,一旦我有這個戰略目標,我怎麼能指示思考庫過濾器類只保留那些匹配根據程序員定義的策略類?

UPDATE:

顯然濾波部分不是最困難的任務(感謝您的回答@MvG),但實際上收集所有的類進行過濾(一般類由定義了一組基本包程序員)。 所以這個想法是查詢所有的類,然後用方法過濾它們: ReflectionUtils.getAll(allClasses, predicate)

然後,爲了獲得要過濾的類的初始集合,我嘗試在程序員選擇的特定包中查詢Object的所有子類型。

下面我用這個代碼:

ConfigurationBuilder config = new ConfigurationBuilder(); 
FilterBuilder fb = new FilterBuilder(); 
fb.include(FilterBuilder.prefix("my.package.prefix")); 
config.filterInputsBy(fb); 
config.setUrls(ClasspathHelper.forPackage("my.package.prefix")); 
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored 
Reflections reflections = new Reflections(config); 
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class); 

這是最好的(更有效)的解決方案?

有人有其他想法嗎?提前致謝 !

回答

1

使用com.google.common.base.Predicate表達您的策略,或將自己的策略對象包裝到這些謂詞中。然後,你可以寫

ReflectionUtils.getAll(allClasses, predicate); 

看來,實際計算該allClasses可迭代的將是更艱鉅的任務。乍看之下,我看不到任何簡單的API。您可能必須直接訪問底層商店,並將類名稱自己變爲Class對象。這意味着加載所有的類,這可能會非常耗時,甚至在某些情況下可能會失敗。

相關問題