Blog

Das Problem mit proxy-basierten AOP-Frameworks

Vincent Partington

Aktualisiert Oktober 23, 2025
2 Minuten
Proxy-basierte AOP-Frameworks wie das Spring Framework haben ein nicht oft diskutiertes Problem. Wenn eine Methode in einer Klasse eine andere Methode in derselben Klasse (oder einer Oberklasse) aufruft, werden alle Interceptoren für diese zweite Methode nicht ausgeführt. Dieses unerwartete Verhalten kann schwerwiegende Folgen haben, wenn der Interceptor wichtige Dienste wie Transaktionen oder Sicherheit liefert.Nehmen wir an, wir implementieren eine Anwendung für eine Bank, bei der nur bestimmte Mitarbeiter eine Kreditprüfung für verdächtige Transaktionen durchführen dürfen, z.B. solche, die 1 Million Euro übersteigen. Mit Hilfe der aspektorientierten Programmierung kann dies wie folgt implementiert werden: Bei der Verarbeitung durch den Precompiler von AspectJ wird die folgende Woven-Klasse ausgegeben: Wie Sie in der Abbildung sehen können, wird beim Aufruf der Methode processPayment die korrekte Sicherheitsprüfung durchgeführt, wenn die Methode checkCreditRating aufgerufen wird. Dieser Vorkompilierungsschritt wurde jedoch als kompliziert und schwer in den Build-Prozess zu integrieren empfunden (und nicht jede IDE verfügt über entsprechende Plugins). Dies führte zum Aufkommen von proxy-basierten AOP-Lösungen wie dynaop und dem AOP-Framework von Spring. Ein Vorkompilierungsschritt ist nicht mehr erforderlich. Stattdessen wird ein Proxy im laufenden Betrieb erstellt. Dieser Proxy führt die im Aspekt definierte Funktionalität aus, bevor (und nachdem) er die Methode im ursprünglichen Objekt aufruft: Abgesehen davon, dass dieser Ansatz nur das Abfangen von Methoden und nicht die gesamte Bandbreite der AOP-Funktionalität bietet, hat er einen weiteren, nicht oft diskutierten Nachteil. Wenn Sie die Methode checkCreditRating auf dem Proxy aufrufen, wird die Sicherheitsüberprüfung korrekt durchgeführt. Wenn Sie jedoch die processPayment-Methode auf dem Proxy aufrufen (siehe Abbildung), wird die Kontrolle an die processPayment-Methode im ursprünglichen Objekt übergeben, die this.checkCreditRating() direkt aufruft und damit die Sicherheitsüberprüfung umgeht. Dies geschieht, weil this im Originalobjekt auf dieses Objekt selbst und nicht auf den Proxy verweist. Andere Funktionen, die davon ausgehen, dass die Identität des Proxys und die Identität des Originalobjekts identisch sind, schlagen ebenfalls fehl. Wie in GoF auf Seite 178 bei der Besprechung des Decorator-Musters erwähnt:
3. Ein Dekorator und seine Komponente sind nicht identisch. Ein Dekorator wirkt wie eine transparente Hülle. Aber vom Standpunkt der Objektidentität aus gesehen ist eine dekorierte Komponente nicht mit der Komponente selbst identisch. Sie sollten sich also nicht auf die Objektidentität verlassen, wenn Sie Dekoratoren verwenden.
Dies ist ein unerwartetes Ergebnis der proxy-basierten Implementierung von AOP und eines, das Sie besonders beachten müssen, wenn Sie wichtige Funktionen in einem Aspekt implementieren!

Verfasst von

Vincent Partington

Contact

Let’s discuss how we can support your journey.