, der den vorherigen Wert in AspectJ-Sollpunktraster freigibt

8

Ich muss Felder Wertänderungen erkennen. Ich möchte den vorherigen Wert mit dem neuen vergleichen. Ich kenne den Feldnamen oder seinen Typ nicht. (Mehr Hintergrund hier . ) Für eine gegebene Klasse:

%Vor%

Ich habe diesen Aspekt: ​​

%Vor%

Das Problem besteht darin, dass args den Wert anzeigt, der an dem Feldsatz-Gelenkpunkt übergeben wurde, und nicht den aktuellen Wert des Felds. In dieser Präsentation auf Seite 27 habe ich Folgendes gefunden:

%Vor%

scheint aber nicht mit meinem Code (Anmerkungen) zu kompilieren. Als ich es versuchte:

%Vor%

Dann habe ich:

%Vor%

Dies ist eine funktionierende Lösung mit Reflektion:

%Vor%

Dies ist eine Lösung mit besserer Leistung als Reflektion (glaube ich). Aber es gibt immer noch einen großen Aufwand (zusätzliches Feld und bindende Aspektinstanz für jedes Ziel).

%Vor%

und hier ist eine Lösung mit declare Eltern:

%Vor%

Es gibt drei Alternativen:

  • pertarget / perthis ringsum mit Feldwerten Karte
  • gesetzt
  • Singleton um mit Reflexion gesetzt
  • singleton ringsum mit declare Eltern und Feldwerten map
  • gesetzt

Die beste Lösung wäre, den vorherigen Wert direkt aus dem Pointcut zu erhalten (ohne Reflektion oder Erinnern von Feldwerten zwischen Pointcuts). Ist es möglich? Wenn nicht, welche Alternative hat die beste Leistung?

Zusätzliche Anmerkungen

Ich fand diese Diskussion über den vorherigen Wert im Set Pointcut, aber es ist ziemlich alt .

Dieser Mechanismus ist für JSF-Session-Scoped Bean interne Statusänderungen - Fix für Google App Engine. Solch eine Bohne hat normalerweise weniger als 100 Felder. Alles wird von einem Thread aufgerufen.

    
zacheusz 25.07.2011, 14:36
quelle

3 Antworten

5

leider gibt es derzeit keine eingebaute Funktion in AspectJ, um den alten Wert des Feldes zu sehen.

Die zwei Lösungen, die Sie bereits erhalten haben, sind ziemlich Standard, und wahrscheinlich ist die Reflexion in diesem Fall die beste.

Eine andere Option ist:

%Vor%

(Ich habe diesen Code hier geschrieben, damit es Fehler geben kann)

Aber dies erstellt eine Karte, um jede Instanz zu verfolgen, und ein zusätzliches Feld in jeder Instanz, um diese Karte zu speichern, so dass Sie mehr oder weniger denselben Overhead des Pertarget-Aspekts erhalten.

Ich verwende derzeit einen ähnlichen Aspekt, aber in diesem Fall brauche ich diese Karte für die json-Serialisierung (sie ist viel schneller als die Reflexion), und die Fähigkeit, alte Werte zu sehen, ist nur ein Nebeneffekt.

    
Simone Gianni 21.07.2011 21:19
quelle
3

Es gibt eine bessere Lösung. Es hat eine bessere Leistung als die Reflexion.

%Vor%

Ich weiß, dass du geschrieben hast, dass du "keine Feldwerte zwischen Punktzeichen speichern willst". AFAIK gibt es keinen anderen Weg.

    
Mike 20.07.2011 00:58
quelle
2

Es sieht so aus, als ob diese Folie eine frühe Version von AspectJ verwendet. Ein Portierungshandbuch sagt, dass das Entfernen von "s" in den Pointcuts für ältere Ratschläge notwendig ist.

Hier ist ein Tipp von einem anderen Tutorial , das nicht funktioniert t verwende die Anmerkungen in AspectJ:

%Vor%

In Bezug auf Ihren Code:

  • Wenn Sie Ihren Rat anwenden, nachdem das Set passiert ist, fühlt sich das ein bisschen merkwürdig an. Den Rat als "vorher" anzuwenden, erscheint verständlicher.
  • Der neue Wert ist ein Argument für den Joinpoint, nicht für den Pointcut. Der Pointcut gibt das alte Argument an. Leider sind in diesem Beispiel sowohl der Typ als auch der Feldname bekannt. Damit kann auf den Hinweis verwiesen werden.

Muss gebunden werden

In einer anderen Diskussion sieht es so aus, als ob es keinen Weg gibt, den aktuellen Stand zu bekommen Wert des Feldes, das gesetzt wird (oder sein Typ), ohne die Information in der Signatur des Joinpoints zu binden.

    
Atreys 14.07.2011 18:58
quelle

Tags und Links