web-dev-qa-db-ja.com

Java-注釈付きクラスのロード

Javaでプラグインクラスをロードするための素晴らしいツールセットがあることは知っていますが、今日、アイデアが浮かびました。

パッケージ "org.home.junk"に多数の注釈付きクラスと注釈なしクラス(注釈 "@AnnotatedClass"で注釈付き)があり、それらのクラスに "@AnnotatedMethod"という注釈付きのメソッドがある場合はどうなりますか。

最初の質問:実行時にその特定のパッケージ内のすべてのクラスの配列/コレクションを取得できるので、どのクラスに注釈が付けられているかを確認できますそれらのインスタンスを作成します。 (ただし、Some.classにこのガイドの厚意による注釈があるかどうかを確認する方法は知っています: http://isagoksu.com/2009/development/Java/creating-custom-annotations-and-making-use-of -それら/

2番目の質問:-最初の質問でやりたいことができる場合-これを行うには最も政治的な方法は何ですか?

JUnitがテストケースクラスをいくつかの同様の方法でロードすることを理解しているので、それは可能だと思います。

また、これが最小限のサードパーティのライブラリなどで実行できれば、すばらしいでしょう。可能であれば:)

23
Xeperis

最初の答え:このプロジェクト を見てください。

Reflections reflections = new Reflections("org.home.junk");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class);

org.home.junkアノテーションが付けられたjavax.persistence.Entityからすべてのクラスを返します。

2番目の回答:上記のクラスの新しいインスタンスを作成するには、これを行うことができます

for (Class<?> clazz : annotated) {
    final Object newInstance = clazz.newInstance();
}

これがすべてに答えることを願っています。

28
Kowser

これは、リフレクションの問題ではなくクラスローダーの問題であるため、ファイルシステムをチェックする手法で実行できます。これを確認してください: リフレクションを使用してパッケージ内のすべてのクラスを見つけることができますか?

ディレクトリに存在するすべてのクラスファイルを確認できれば、このメソッドを使用して対応するクラスを簡単に取得できます。

Class<?> klass = Class.forName(className)

クラスに注釈が付けられているかどうかを知ることは、リフレクションの問題です。クラスで使用されている注釈を取得する方法は次のとおりです。

Annotation[] annotations = klass.getAnnotations();

実行時に表示される保持ポリシータイプを使用してカスタムアノテーションを必ず定義してください。

@Retention(RetentionPolicy.RUNTIME) 

この記事は、その詳細についての優れたリソースです: http://tutorials.jenkov.com/Java-reflection/annotations.html

2
gersonZaragocin

それはすべて、アノテーションに対してどのような要件があるかに依存します。

たとえば@EJB:このアノテーションは、コンテナがEJB固有の作業を識別および実行するように設計されています。この作業では、ファイル全体をスキャンしてから、そのようなクラスを見つける必要があります。

ただし、アノテーションに基づく特定の機能を有効にすることだけが要件である場合は、Javaリフレクションのみを使用して行うことができます。

例えば@NotNull:この注釈は、注釈付き要素がnullでないことを確認するためにJSR 303で設計されています。この機能は、リフレクションAPIを使用して実行時に簡単に実装できます

1
Amit Deshpande

Spring(サードパーティ、ごめんなさい:-))をお持ちの場合は、 org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider を使用してください

コードの使用例は this SO question にあります

1
Vitaliy