13 Stimmen

Wie kann ich alle Klassen auf dem Klassenpfad finden, die eine bestimmte Methodenannotation haben?

Ich möchte einen Intialisierungsmechanismus in Java implementieren, der auf Annotationen basiert. Genauer gesagt, habe ich eine Annotation definiert:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Initialization {

/**
 * If the eager initialization flag is set to <code>true</code> then the
 * initialized class will be initialized the first time it is created.
 * Otherwise, it will be initialized the first time it is used.
 * 
 * @return <code>true</code> if the initialization method should be called
 *         eagerly
 */
boolean eager() default false;

}

Außerdem habe ich eine Schnittstelle:

public interface SomeKindOfBasicInterface {}

Ich möchte jede Implementierung des SomeKindOfBasicInterface Klasse auf meinem Klassenpfad, die die @Initialization Anmerkung zu einer Methode. Ich schaue mir Spring's MetaDataReader Tools, die am besten geeignet sind, um das Laden der anderen SomeKindOfBasicInterface Implementierungen, während ich dies tue ... aber ich bin nicht sicher, wie man eine Suche wie ich beschreiben zu tun. Irgendwelche Tipps?

0 Stimmen

10voto

Kaitsu Punkte 4054

Sie könnten verwenden Reflexionen ein Werkzeug zur Analyse von Java-Laufzeit-Metadaten. Ich habe es verwendet, um alle Subtypen eines bestimmten Typs zu erhalten, aber es kann auch Ihren Fall behandeln.

6 Stimmen

Ich würde dringend empfehlen, keine Reflexion oder grundsätzlich den Classloader zu verwenden, wenn Zeit- und Raumersparnis auch nur im Entferntesten von Bedeutung sind. Sie können eine Tonne von Klassen in Ihrem Klassenpfad haben und alle diese geladenen Klassen sind jetzt in permgen. Verwenden Sie etwas wie ASM (oder eine Bytecode-Bibliothek) und lesen Sie einfach Byte[]s, verwenden Sie die ASM-Bibliothek, um die Informationen über die Klasse zu erhalten, z. B. "ist es mit x annotiert?" und dann und nur dann tatsächlich diese Klasse laden (wenn Sie diese Klasse benötigen).

0 Stimmen

@alphazero: Nachdenken s verwendet eigentlich nicht java.lang.reflect als solches. Es verwendet, ähnlich wie die von Ihnen beschriebene Methode, Javassist zum Lesen von Klassen-Metadaten, um das eigentliche Laden von Klassen zu vermeiden.

0 Stimmen

@Nicholas Ich würde denken, dass ist JVM-Implementierung spezifisch. Ich habe keinen Blick in die Spezifikation geworfen. (Wenn das tatsächlich so spezifiziert ist ("use javassist"), wäre ich für einen Link dankbar!

1voto

krosenvold Punkte 73093

Ich würde grundsätzlich eine BeanPostProcessor Implementierung, möglicherweise auf der Grundlage der CommonAnnotationBeanPostProcessor . Dann würde ich mich für Komponenten-Scan der den Klassenpfad durchsucht und alle Beans auswählt, die Ihrer Spezifikation entsprechen. Wenn die Bean initialisiert ist, wird Ihr Postprozessor ausgeführt.

Ich sehe, ich gehe davon aus, dass Sie nach Bohnen suchen. Wenn das nicht der Fall ist, müssen Sie möglicherweise den Klassenpfad selbst durchsuchen.

1voto

Chochos Punkte 5120

Sie können verwenden javassist um die Anmerkungen in Ihren Klassen zu finden, noch bevor Sie sie laden, aber Sie müssen die .class-Dateien direkt lesen, was bedeuten kann, dass Sie ein JAR selbst öffnen müssen, usw. Außerdem müssen Sie wissen, wo Sie nach den Klassen suchen müssen. Sie können die Laufzeitumgebung nicht einfach nach allen Unterklassen Ihrer BasicInterface .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X