Beachten Sie, dass diese Arbeit, die Sie brauchen, um zu definieren Petals ServiceProviderInterface (SPI) und erklären, dass Ihre Implementierungen. Sie tun das, indem Sie eine Datei erstellen, in resources/META-INF/services mit dem Namen examples.reflections.Pet und erklären alle Implementierungen von Pet im es
Beachten Sie, dass nur Pakete, die bekannt sind, um die ClassLoader in dieser Zeit geladen werden, die durch einen Aufruf Package.getPackages().
Darüber hinaus gibt es andere Ansätze basieren auf URLClassLoader, wird immer begrenzt sein, um Klassen, die bereits geladen wurde, es sei denn, Sie tun eine Verzeichnis-basierte Suche.
Im Allgemeinen, es ist teuer, dies zu tun. Die Verwendung der Reflexion, die Klasse geladen werden muss. Wenn Sie laden möchten, an die jeder Klasse zur Verfügung, die auf den classpath, das braucht Zeit und Speicher, und ist nicht zu empfehlen.
Wenn Sie dies vermeiden möchten, würden Sie brauchen, um Ihre eigenen Klassen-Datei-parser, die effizienter betrieben, statt der Reflexion. Ein byte code engineering library kann helfen, mit diesem Ansatz.
Den Service Provider Mechanismus ist mit den herkömmlichen Mitteln auflisten Implementierungen eines pluggable service. Verwenden Sie die ServiceLoader in Java 6, oder der Umsetzung Ihrer eigenen in früheren Versionen. Ich ein Beispiel in einer anderen Antwort.
Ja, der erste Schritt ist die Identifizierung von "alle" die Klassen, die Sie sich sorgte. Wenn Sie diese Informationen bereits haben, können Sie auflisten, durch jeden von Ihnen, und verwenden instanceof überprüfen der Beziehung. Ein Artikel ist hier: http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
Den Apache-BCEL-Bibliothek ermöglicht das Lesen von Klassen, ohne Sie zu laden. Ich glaube, es wird schneller sein, weil Sie in der Lage sein sollten, überspringen Sie die Verifizierung Schritt. Das andere problem mit dem laden von allen Klassen mit dem classloader ist, dass Sie leiden, einen riesigen Arbeitsspeicher sowie versehentlich ausführen statischen code-Blöcke, die Sie wahrscheinlich nicht wollen, zu tun.
Auch, wenn Sie schreiben eine IDE-plugin (wobei das, was Sie zu tun versuchen, ist relativ Häufig), dann ist die IDE in der Regel bietet Ihnen effiziente Möglichkeiten, um den Zugriff auf die Klassen-Hierarchie des aktuellen Zustands des Benutzer-Codes.
Ich lief in das gleiche Problem. Meine Lösung war der Einsatz von Reflexion zu untersuchen, alle Methoden in einer ObjectFactory-Klasse, wodurch diejenigen, die nicht waren createXXX () - Methoden geben eine Instanz von einer meiner gebunden POJOs. Jede Klasse, so entdeckt wird Hinzugefügt, um eine Klasse [] - array, das wurde dann an der JAXBContext Instanziierung aufrufen. Dies funktioniert gut, braucht nur zum laden der ObjectFactory-Klasse, die etwa erforderlich sein werden, sowieso. Ich brauche nur zur Aufrechterhaltung der ObjectFactory-Klasse, eine Aufgabe entweder von hand durchgeführt (in meinem Fall, denn ich begann mit POJOs und verwendet schemagen), oder kann erzeugt werden, wie benötigt von xjc. So oder so, es ist performant, einfach und effektiv.
Versuchen ClassGraph. (Disclaimer, ich bin der Autor). ClassGraph unterstützt das Scannen für Klassen, die die Implementierung eines bestimmten interface, entweder zur Laufzeit oder zur build-Zeit, aber auch viel mehr. ClassGraph aufbauen kann, eine abstrakte Repräsentation der gesamten Klasse graph (alle Klassen, annotations, Methoden, Methodenparameter und-Felder) in Erinnerung, für alle Klassen auf dem Klassenpfad, oder für Klassen, die in der Whitelist-Pakete, und Sie können die Abfrage, die die Klasse graph immer Sie wollen. ClassGraph unterstützt mehr classpath Spezifikation Mechanismen und classloadern als alle anderen scanner, und arbeitet auch nahtlos mit dem neuen JPMS-Modul-system, so dass, wenn Sie stützen Ihren code auf ClassGraph, Ihr code wird maximal tragbar. Finden Sie in der API hier.
Was erickson gesagt hat, aber wenn Sie wollen immer noch, es zu tun, dann werfen Sie einen Blick auf Reflexionen. Von deren Seite:
InformationsquelleAutor der Antwort Peter Severin
Habe ich die Suche für eine Weile und es scheint verschiedene Ansätze, hier eine Zusammenfassung:
Reflexionen Bibliothek ist sehr beliebt, wenn u don ' T Geist hinzufügen der Abhängigkeit. Es würde dann so Aussehen:
ServiceLoader (nach erickson Antwort) und würde es wie folgt Aussehen:
Beachten Sie, dass diese Arbeit, die Sie brauchen, um zu definieren
Pet
als ServiceProviderInterface (SPI) und erklären, dass Ihre Implementierungen. Sie tun das, indem Sie eine Datei erstellen, inresources/META-INF/services
mit dem Namenexamples.reflections.Pet
und erklären alle Implementierungen vonPet
im esPaket-level-annotation. hier ist ein Beispiel:
und die annotation definition:
und Sie müssen erklären das Paket-level annotation in einer Datei namens
package-info.java
innerhalb dieses Pakets. hier sind Beispiel-Inhalt:Beachten Sie, dass nur Pakete, die bekannt sind, um die ClassLoader in dieser Zeit geladen werden, die durch einen Aufruf
Package.getPackages()
.Darüber hinaus gibt es andere Ansätze basieren auf URLClassLoader, wird immer begrenzt sein, um Klassen, die bereits geladen wurde, es sei denn, Sie tun eine Verzeichnis-basierte Suche.
InformationsquelleAutor der Antwort Ahmad Abdelghany
Im Allgemeinen, es ist teuer, dies zu tun. Die Verwendung der Reflexion, die Klasse geladen werden muss. Wenn Sie laden möchten, an die jeder Klasse zur Verfügung, die auf den classpath, das braucht Zeit und Speicher, und ist nicht zu empfehlen.
Wenn Sie dies vermeiden möchten, würden Sie brauchen, um Ihre eigenen Klassen-Datei-parser, die effizienter betrieben, statt der Reflexion. Ein byte code engineering library kann helfen, mit diesem Ansatz.
Den Service Provider Mechanismus ist mit den herkömmlichen Mitteln auflisten Implementierungen eines pluggable service. Verwenden Sie die
ServiceLoader
in Java 6, oder der Umsetzung Ihrer eigenen in früheren Versionen. Ich ein Beispiel in einer anderen Antwort.InformationsquelleAutor der Antwort erickson
Frühjahr hat eine ziemlich einfache Weise zu erreichen:
Dann können Sie autowire eine Liste des Typs
ITask
Frühjahr und füllen Sie es mit allen Implementierungen:InformationsquelleAutor der Antwort kaybee99
Ja, der erste Schritt ist die Identifizierung von "alle" die Klassen, die Sie sich sorgte. Wenn Sie diese Informationen bereits haben, können Sie auflisten, durch jeden von Ihnen, und verwenden instanceof überprüfen der Beziehung. Ein Artikel ist hier: http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
InformationsquelleAutor der Antwort Zhichao
Was erikson gesagt am besten ist. Hier ist ein Fragen und Antwort thread - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
Den Apache-BCEL-Bibliothek ermöglicht das Lesen von Klassen, ohne Sie zu laden. Ich glaube, es wird schneller sein, weil Sie in der Lage sein sollten, überspringen Sie die Verifizierung Schritt. Das andere problem mit dem laden von allen Klassen mit dem classloader ist, dass Sie leiden, einen riesigen Arbeitsspeicher sowie versehentlich ausführen statischen code-Blöcke, die Sie wahrscheinlich nicht wollen, zu tun.
Den Apache-BCEL-Bibliothek link - http://jakarta.apache.org/bcel/
InformationsquelleAutor der Antwort
Auch, wenn Sie schreiben eine IDE-plugin (wobei das, was Sie zu tun versuchen, ist relativ Häufig), dann ist die IDE in der Regel bietet Ihnen effiziente Möglichkeiten, um den Zugriff auf die Klassen-Hierarchie des aktuellen Zustands des Benutzer-Codes.
InformationsquelleAutor der Antwort Uri
Ich lief in das gleiche Problem. Meine Lösung war der Einsatz von Reflexion zu untersuchen, alle Methoden in einer ObjectFactory-Klasse, wodurch diejenigen, die nicht waren createXXX () - Methoden geben eine Instanz von einer meiner gebunden POJOs. Jede Klasse, so entdeckt wird Hinzugefügt, um eine Klasse [] - array, das wurde dann an der JAXBContext Instanziierung aufrufen. Dies funktioniert gut, braucht nur zum laden der ObjectFactory-Klasse, die etwa erforderlich sein werden, sowieso. Ich brauche nur zur Aufrechterhaltung der ObjectFactory-Klasse, eine Aufgabe entweder von hand durchgeführt (in meinem Fall, denn ich begann mit POJOs und verwendet schemagen), oder kann erzeugt werden, wie benötigt von xjc. So oder so, es ist performant, einfach und effektiv.
InformationsquelleAutor der Antwort NDK
Versuchen ClassGraph. (Disclaimer, ich bin der Autor). ClassGraph unterstützt das Scannen für Klassen, die die Implementierung eines bestimmten interface, entweder zur Laufzeit oder zur build-Zeit, aber auch viel mehr. ClassGraph aufbauen kann, eine abstrakte Repräsentation der gesamten Klasse graph (alle Klassen, annotations, Methoden, Methodenparameter und-Felder) in Erinnerung, für alle Klassen auf dem Klassenpfad, oder für Klassen, die in der Whitelist-Pakete, und Sie können die Abfrage, die die Klasse graph immer Sie wollen. ClassGraph unterstützt mehr classpath Spezifikation Mechanismen und classloadern als alle anderen scanner, und arbeitet auch nahtlos mit dem neuen JPMS-Modul-system, so dass, wenn Sie stützen Ihren code auf ClassGraph, Ihr code wird maximal tragbar. Finden Sie in der API hier.
InformationsquelleAutor der Antwort Luke Hutchison