Ändern einer Methode mithilfe von Anmerkungen
Wie kann ich ändern, was eine Methode in Java ?
Ich meine, ich bin versucht, Anmerkungen zu machen, den folgenden code
@Anno1(Argument = "Option1")
public class TestClass
{
@Anno2
public void test()
{
}
}
In
public class TestClass
{
private static StaticReference z;
public void test()
{
z.invokeToAll();
}
}
Dies ist ein sehr Vereinfachtes Beispiel, was ich versuche zu tun. Anno1
haben viele mögliche Kombinationen, aber das ist nicht mein problem, so weit. Mein problem ist, wie Sie code hinzufügen, um die Methode test()
Ich bin auf der Suche nach einer generischen Lösung, wenn möglich. ZB. Ein Weg, um fügen Sie jede Art von code in der Methode (nicht nur ein Weg, um .invokeToAll()
)
Bisher bin ich mit import javax.annotation.processing.*;
und ich habe den folgenden code, aber ich weiß nicht, wie es weiter gehen von dort aus
private void processMethodAnnotations(RoundEnvironment env)
{
for (Element e : env.getElementsAnnotatedWith(Anno2.class))
{
//If it is a valid annotation over a method
if (e.getKind() == ElementKind.METHOD)
{
//What to do here :S
}else
{
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);
}
}
}
Ich habe etwas gefunden, über die Java-Reflection, aber ich habe nicht gefunden eine Quelle, um mir zu helfen mit dem, was ich Tue.
Natürlich habe ich extends AbstractProcessor
in meinem code
Ich gefunden haben, dieses tutorial (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm), Aber dies betrifft eine neue Klasse zu erstellen, nicht nur die änderung der Methode. und die javax.lang.model.elements
bieten keine Möglichkeit zum Bearbeiten der Elemente (die in meinem Fall stellt eine Methode).
Ich hoffe meine Frage ist klar und inline mit den Regeln. Falls nicht, bitte Kommentar, und ich werde das klären. Danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Annotation Verarbeitung ist der falsche Weg für Sie, die von Wikipedia:
Menschen, schlug Sie Recht Weg - AOP. Speziell können Sie verwenden AspectJ. "Schnelle Ergebnisse" Weg ist (wenn Sie Eclipse verwenden):
1) Installieren AJDT (AspectJ Development Tools)
2) Erstellen AspectJ-Projekt und fügen Sie dort Ihre Klassen und Anmerkungen
3) Erstellen Aspekt:
nun führen Sie einen test und Sie werden sehen, dass es funktioniert 😉 AJDT kompiliert den code für Sie automatisch, so brauchen keine manuelle Arbeit zu tun, hoffe, das ist das, was du als "Magie" 😉
UPDATE:
wenn Ihr code in der test () - Methode hängt davon ab, Anno1 Anmerkung Wert, dann wird im inneren Aspekt, die Sie bekommen können Klasse-Anmerkung für die, die es ausgeführt wird, auf diese Weise:
wo thisJoinPoint ist eine Besondere Referenzvariable.
UPDATE2:
wenn Sie hinzufügen möchten
System.out.println( this )
in Ihrem Aspekt, den Sie schreiben müssen, esSystem.out.println( thisJoinPoint.getThis() )
, gerade getestet und es funktioniert.thisJoinPoint.getThis()
gibt Sie "dies" aber nicht genau; in der Tat ist dies-Objekt-variable und wenn Sie möchten, um alle Anwesen, die Sie brauchen, entweder zu werfen oder zu reflektion verwenden. UndthisJoinPoint.getThis()
keinen Zugriff auf private Eigenschaften.Gut, jetzt scheint, dass Ihre Frage beantwortet ist, aber wenn ich nichts übersehen habe, oder Sie bekommen zusätzliche Frage/Probleme mit dieser Art und Weise fühlen Sie sich frei zu Fragen 😉
Javassist
). Ich eh schon gab Sie +1 und jetzt eine Akzeptierte Antwort für die Mühe und gute Antwort. Vielen Dank!Academic Restrictions
;). Vielen Dank für Ihre Hilfe though.Es ist durchaus möglich, das zu tun, was Sie Fragen, zwar gibt es eine Einschränkung: sich auf eigenes compiler-APIs. Klingt gruselig, ist es aber nicht wirklich (compiler-Implementierungen neigen stabil zu sein).
Es ist ein Papier, das erklärt das Verfahren: Der Hacker ' s Guide to Javac.
Vor allem, das wird von Projekt Lombok, um die automatische getter/setter-generation (unter anderem). Die folgende Artikel erklärt, wie er es tut, im Grunde re-iterieren, was gesagt wird, den oben genannten Papier.
Gut, man könnte sehen, ob die folgenden boilerplate-code wird für Sie nützlich sein:
Als alternative Ihre macht einsetzen, Aspekt orientierte Programmierung, zum Beispiel, Sie haben die AspectJ Projekt.
z.invokeToAll();
ich möchte zum Beispiel etwas zu tun, wieSystem.out.println(this);
ich bin auf der Suche nach einer generischen Lösung, wenn möglich.this
bedeutet zum aufrufenTestClass.toString()
. Sie können immer noch tun, wenn Sie bevorzugen. Darüber hinaus, mit der Reflexion, haben Sie Zugriff auf alle Eigenschaften der annotierten Klassen.Ich bin mir nicht sicher, ob es überhaupt möglich ist zu ändern Sie die Quell-oder byte-code mit Anmerkungen. Von dem, was Sie beschreiben, es sieht aus, als wenn Aspekt orientierte Programmierung könnte eine Lösung für Ihr problem.
Ihre Anmerkungen sind ziemlich ähnlich der pointcut Konzept (Sie markieren einen Ort, wo muss der code eingefügt werden) und der eingefügte code ist in der Nähe der Beratung Konzept.
Ein anderer Ansatz wäre, das Parsen von java-Quellcode-Datei in einen abstrakten syntax Baum, ändern Sie diesen AST und serialisieren eines java-compiler-Eingabe.
Wenn Ihre Klasse erweitert eine geeignete Schnittstelle, könnten Sie wickeln Sie es in ein DynamicProxy, die delegiert alle Aufrufe an die original-Methoden, außer den Anruf zu testen.