2016-09-29 3 views
9

Ich stelle eine API bereit und muss wissen, wo Methoden der API aufgerufen wurden. Ich könnte natürlich Reflektion oder den Thread Stacktrace verwenden, aber das würde eine Menge Laufzeitkosten beinhalten.So ermitteln Sie, wo die Methode aufgerufen wurde

Ich brauche nicht den genauen Klassennamen, eine eindeutige Referenz pro Aufruf wäre ausreichend. In C würde ich normalerweise den Präprozessor verwenden, um automatisch den Methodenaufruf __FILE__ und __LINE__ hinzuzufügen.

Gibt es in Java (neben der Codegenerierung) eine Methode, um eine eindeutige Anruferidentifikation mit geringen Laufzeitkosten zu erhalten?

+2

Mögliches Duplikat von http://stackoverflow.com/questions/26425049/how-to-get-a-unique-method-identifier –

+2

Frage nur: Welches Problem wollen Sie hier lösen? – GhostCat

+2

Können Sie sich AspectJ anschauen und einen Join-Punkt einrichten, wenn Ihre API aufgerufen wird? –

Antwort

3

Eine Lösung wäre eine im Cache gespeicherte Throwable zu haben, die in übergeben wird

class StackPoint { 
    Throwable stack; 
    public Throwable getStack() { 
     if (stack == null) 
      stack = new Throwable(); 
     return stack; 
    } 
} 

public void methodToCall(StackPoint sp) { 
    Throwable t = sp.getStack(); 

} 


static final StackPoint one = new StackPoint(); 

methodToCall(one); // Have to remember to give each line a different StackPoint. 

. Hinweis: Wenn die Methode, die diese Anrufer Änderungen ruft, können Sie nur die erste Aufzeichnung aller Zeiten.


Es gibt kein Standardmuster und es ist wahrscheinlich, dass, wenn Sie dies effizient sein mögen, müssen die Anrufer eine eindeutige ID zu übergeben. Das nächste, was Sie tun können, ist ein Lambda.

public void methodToCall(Runnable run) { 
    Class id = run.getClass(); 

} 

Sie können es nennen wie diese

methodtoCall(()->{}); 

eine andere Klasse für jeden Ort Dies wird schaffen es genannt wird, auch wenn es mehrere Male auf der gleichen Zeile angezeigt. Es erstellt keinen Müll, da es jedes Mal das gleiche Objekt wiederverwendet. Sie könnten diese kürzer mit

void methodToCall(IntFunction fun) { 

} 

machen und

methodToCall(a->1); 
+0

Während ich Call-Sites nicht verbieten kann, die dasselbe Argument zweimal durchlaufen, ist dies eine wirklich nette Lösung. Wenn das übergebene Argument unbekannt ist, werde ich den Stacktrace verwenden, um die genaue Aufruf-Site zu erhalten und ansonsten die zwischengespeicherte Information zu verwenden. – ooxi

+1

Aber auf Lambdas Identität zu zählen ist falsch, nicht wahr? –

+1

@ooxi geben den Anrufer-Code, den sie kopieren und einfügen können, ohne sie manuell ändern zu müssen, bedeutet, dass sie weniger damit herumhantieren. –

1

nennen Als etwas asynchron beteiligt ist, spaltete den Anruf, und lassen Sie die API die ID zurück.

Ticket callTicket = api.call(params); 
Logger.getLogger(getClass().getName(), Level.FINE, callTicket); 
Result result = callTicket.get(); 

Oben ein Ergebnis zurückgegeben (synchron) ist wahrscheinlich nicht der Fall mit Ihrem Code. Ihr Code wird das Ergebnis an anderer Stelle erhalten. Aber das könnte auch ein Ticketsystem sein.

+0

Aber wie kann ich feststellen, ob ein neues Ticket zurückgegeben werden soll, ohne den StackTrace zu überprüfen? – ooxi

+1

Jeder Aufruf in der gleichen Klasse und Zeile zeichnet ein neues Ticket aus der API. Zum Beispiel protokollieren. Bei einer asynchronen Ausnahme ist das Ticket bekannt und man kann in den Protokollen suchen. Sicherlich eine andere Herangehensweise und Perspektive. –

+0

Ich bevorzuge natürlich Ihre Lösung, da es den Code des Clients nicht mit technischen Details schneidet. Nichtsdestotrotz behalte ich die Antwort von @PeterLawrey als akzeptiert, da sie die Frage direkter löst. – ooxi

Verwandte Themen