2012-04-01 8 views
0

は私のプロジェクトのソースファイル間、私はこれらの倍数を持って検索は

@Name("name1") 
public static Foo foo = new Foo(); 

を次のようにこれが使用されようとしている

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface Name 
{ 
    String value(); 
} 

私はこの注釈があるとします。 @Nameの前にあるすべての "foo"を検索して収集する方法は簡単ですか? つまり、これらを含むSet<Foo>を返すメソッドを記述したいと思います。

ありがとうございました!

+0

Javaでは? unixのcmd行を使用すると、find + grep – ControlAltDel

+0

@ user1291492を使用するとかなり簡単になります。保持はRUNTIMEです。このメソッドは、ソースコードにアクセスすることも、アクセスしないこともあります。 OTH、おそらくクラスファイルはgreppableです。 – emory

+0

少し話題になっていますが、なぜ「Set 」が必要ですか? 'Map 'や名前のポイントは何かを作る方が意味があるようです。 – emory

答えて

2

他の人が提案しているクラスパススキャナにはあまり慣れていません。彼らは、理想的ではないにしても堅牢なソリューションのように見えます。

ソースを制御できる場合は、アノテーション処理を使用できます。

スタティックメンバーがMap<String,Foo>MapClassクラスを作成するアノテーションプロセッサを作成します。注釈プロセッサは、@ Name注釈に遭遇するたびに、それをMapClassのソースコードに追加する。注釈の処理が終了すると、マップをハードコーディングした場合と同じ効果が得られます。

コンパイル時にアノテーション処理が行われます。あなたのプロジェクトのいくつかのクラスがあなたによってコンパイルされていない場合。たとえば、他の人がクラスをコンパイルしてjarファイルを与えると、簡単には動作しません。しかし、すべてのクラスがあなたによってコンパイルされていれば、それは問題ではありません。

アノテーションプロセッサを作成するには、AbstractProcessorを拡張します。 @ SupportedAnnotationTypes ("Name")注釈でクラスに注釈を付ける必要があります(名前が注釈の完全修飾名であることを確認してください)。

processメソッドをオーバーライドします。 processは、2つのパラメータ:annotationsroundEnvを持っています。 annotationsは、この特定のプロセッサがサポートしているアノテーションのセットです。あなたのケースでは(Name)でなければなりません。 roundEnvは有用なユーティリティクラスです。

annotationsで1つの注釈を繰り返します。 roundEnvgetElementsAnnotatedWithを使用してください。これにより、@Nameアノテーションを持つすべての要素のセットが得られます。

AbstractProcessorには、別のユーティリティーメンバー - processingEnvがあります。そのgetFilerメソッドをcreateSourceFileに使用してください。

コンパイルを少し修正する必要があります。プロセッサを別々に、他のクラスの前にコンパイルする必要があります。プロセッサがコンパイルされ、他のクラスをコンパイルした後、プロセッサについてコンパイラに通知する必要があります。コマンドラインを使用している場合は、-processorpath /path/to/processor/class[es]-processor qualified.name.of.processorを追加します。

クラスパススキャナと比較したこのアプローチの利点は、すべてがコンパイル時に発生することです。たとえば、Bar要素に誤って@Name注釈を追加した場合、プロセッサにコンパイル時エラーが発生する可能性があります(プロセッサが無視できるようにしたい場合)。その後、製品出荷前に修正することができます。クラスパススキャナでは、スローされるエラーは実行時エラーです。これはユーザーに表示されます。

このアプローチの欠点は、すべてがコンパイル時に発生することです。これにより、クラスをプロジェクトに動的に追加することが難しくなります。

+0

これは私が必要とするように聞こえる。しかし、注釈プロセッサはどのように見えますか?そして、@Nameアノテーションにどのように「遭遇する」ことがわかりませんか?それらを見つけるためにまだスキャンする必要はありませんか? – user113454

+0

詳細を教えていただけますか?ありがとう – user113454

+0

@ user1064918私は助けてくれることを願っています。大きな違いは、クラスパススキャナがより堅牢であることだと思います。これはうまくいくでしょう。しかし、あなたのプロジェクトが適切であれば、注釈プロセッサを使う方が適切かもしれません。 – emory

0

いいえ(コードからではありません) ソリューションは、クラスでそれらをすべて入れ、その後、クラスのField S(getFields())に反復してAnnotation S(getAnnotation())あなたはクラスパスのスキャナで必要なもの

1

をチェックすることです。私はMetapossum Scanner(これはmvnリポジトリにあるので勝った)を使用して、注釈付きクラスをスキャンしましたが、注釈付きフィールドをスキャンするとは思いません。

私が調べた他のオプションはReflectionsでした。私はReflectionsを使わず、調査しただけです。ドキュメントには、あなたの必要と思われるようなgetFieldsAnnotatedWithクエリがあります。

クラスパススキャナは控えめであり、クラスパスの中でより多くのものを取得できます。

0

Scannotationをご覧ください!あなたの問題を解決するかもしれません!

Scannotationは、一連の.classファイルからアノテーションデータベースを作成するJavaライブラリです。このデータベースは実際には、どのアノテーションが使用され、どのクラスがそれを使用しているのかを示すマップのセットです。

PS .: VRaptor frameworkは内部的に使用します。