cache cache cache cache cache cache cache cache cache cache cache cache cache cache cache cache cache cache
 

Java - Wie kann ich...?

Drucken
Einen Dynamic Proxy implementieren (1)
Geschrieben von: Christian Jänicke
Samstag, 23. Januar 2010

Ein Dynamic Proxy ermöglicht es, das Verhalten von Methoden eines Objekts zur Laufzeit zu beeinflussen. So ist es möglich, Methoden um bestimmte Funktionen zu erweitern oder sogar Methoden zu deaktivieren. Die Anwendungsgebiete reichen von einfachen Logging-Funktionen, die nachträglich zu Methoden hinzugefügt werden, bis hin zu komplexen Berechtigungsprüfungen, die den Zugriff auf bestimmte Methoden regeln.

Allerdings muss die Verwendung eines Dynamic Proxies frühzeitig in der Systemarchitektur eingeplant werden, da die Methoden eines Objekts nicht mehr innerhalb des Programms direkt aufgerufen werden dürfen, sondern nur noch indirekt über ein spezielles Proxy-Objekt der Klasse java.lang.reflect.Proxy.

Methoden können mit Hilfe von Invocation-Handlern um bestimmte Funktionen erweitert werden. Ein Invocation Handler muss das Interface java.lang.reflect.InvocationHandler implementieren. In dem Interface ist genau eine Methode definiert, die Methode invoke(). Die Methode wird von dem Proxy-Objekt aufgerufen, bevor die eigentliche Methode des Zielobjekts aufgerufen wird. Innerhalb der Methode invoke() muss bzw. kann die Methode des Zielobjekts aufgerufen werden. Auf diese Weise ist es möglich vor und hinter dem Methodenaufruf eigene Programmlogik zu implementieren.

Die genaue Funktionsweise und Implementierung werde ich nun anhand eines Beispiels erläutern. Als erstes muss natürlich eine Klasse mit einer Methode implementiert werden, die später dynamisch erweitert werden soll. Zusätzlich zu der Klasse muss allerdings auch ein Interface definiert werden, in dem alle Methoden deklariert sind, die durch den Dynamic Proxy erweiterbar sein sollen. Das ist mit Sicherheit der grösste Nachteil bei der Verwendung des Dynamic Proxies.

Hello und HelloImpl

Hier also nun das Interface Hello, in dem die Methode sayHello() deklariert ist, die dynamisch erweiterbar sein soll.

public interface Hello {
  public String sayHello(String name);
}

Nun kann in einer eigenen Klasse das Standardverhalten des Interfaces implementiert werden.

public class HelloImpl implements Hello {

  public String sayHello(String name) {
    System.out.println("Hello " + name + "!");
    return "Hello " + name + "!";
  }
}

InvocationHandler

Als nächstes folgt die Implementierung des Invocation Handlers. Zur Erinnerung, der Invocation Handler wird von dem Proxy-Objekt aufgerufen. In dem Interface InvocationHandler muss die Methode invoke() implementiert werden. Die Syntax der Methode ist:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}

Der Parameter proxy gibt hier die Proxy-Instance an, mit der der Invocation Handler aufgerufen wurde und nicht das Zielobjekt, dessen Methoden erweitert werden sollen. Folglich muss im Invocation Handler das Zielobjekt gespeichert werden (z.B. im Konstruktor). Die Methode method und deren Argumente args müssen dann entsprechend auf dem Zielobjekt mittels method.invoke() aufgerufen werden.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class LogHandler implements InvocationHandler {
  private Object object;

  public LogHandler(Object object) {
    this.object = object;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("Invoking method " + method.getName());
    
    Object result = method.invoke(this.object, args);
    
    System.out.println("Done.");
    return result;
  }
}

Proxy

Über den Aufruf Proxy.newProxyInstance() wird das Proxy-Objekt erzeugt, das den Invocation Handler mit der eigenen Klasse verbindet. Als Parameter muss der ClassLoader und das Interface angegeben werden, in dem die Methoden definiert sind, die dynamisch erweiterbar sind.

import java.lang.reflect.Proxy;

public class HelloDemo {

  public static void main(String[] args) {
    HelloImpl helloImpl = new HelloImpl();
      
    ClassLoader loader = helloImpl.getClass().getClassLoader();
      
    Class[] interfaces = new Class[] { Hello.class };
    LogHandler logHandler = new LogHandler(helloImpl);
      
    Hello helloProxy = (Hello) Proxy.newProxyInstance(loader, interfaces, logHandler);
    helloProxy.sayHello("Chris");
  }
}
Zuletzt aktualisiert am Samstag, 23. Januar 2010

Impressum

Impressum

Haftungsausschluss

(1) Haftungsbeschränkung

Inhalte dieser Website

Die Inhalte dieser Website werden mit größtmöglicher Sorgfalt erstellt. Der Anbieter übernimmt jedoch keine Gewähr für die Richtigkeit, Vollständigkeit und Aktualität der bereitgestellten Inhalte. Die Nutzung der abrufbaren Inhalte erfolgt auf eigene Gefahr des Nutzers. Namentlich gekennzeichnete Beiträge geben die Meinung des jeweiligen Autors und nicht immer die Meinung des Anbieters wieder.

Verfügbarkeit der Website

Der Anbieter wird sich bemühen, den Dienst möglichst unterbrechungsfrei zum Abruf anzubieten. Auch bei aller Sorgfalt können aber Ausfallzeiten nicht ausgeschlossen werden. Der Anbieter behält sich das Recht vor, sein Angebot jederzeit zu ändern oder einzustellen.

Externe Links

Diese Website enthält Verknüpfungen zu Websites Dritter ("externe Links"). Diese Websites unterliegen der Haftung der jeweiligen Betreiber. Der Anbieter hat bei der erstmaligen Verknüpfung der externen Links die fremden Inhalte daraufhin überprüft, ob etwaige Rechtsverstöße bestehen. Zu dem Zeitpunkt waren keine Rechtsverstöße ersichtlich. Der Anbieter hat keinerlei Einfluss auf die aktuelle und zukünftige Gestaltung und auf die Inhalte der verknüpften Seiten. Das Setzen von externen Links bedeutet nicht, dass sich der Anbieter die hinter dem Verweis oder Link liegenden Inhalte zu Eigen macht. Eine ständige Kontrolle dieser externen Links ist für den Anbieter ohne konkrete Hinweise auf Rechtsverstöße nicht zumutbar. Bei Kenntnis von Rechtsverstößen werden jedoch derartige externe Links unverzüglich gelöscht.

Werbeanzeigen

Für den Inhalt der Werbeanzeigen ist der jeweilige Autor verantwortlich, ebenso wie für den Inhalt der beworbenen Website. Die Darstellung der Werbeanzeige stellt keine Akzeptanz durch den Anbieter dar.

Kein Vertragsverhältnis

Mit der Nutzung der Website des Anbieters kommt keinerlei Vertragsverhältnis zwischen dem Nutzer und dem Anbieter zustande. Insofern ergeben sich auch keinerlei vertragliche oder quasivertragliche Ansprüche gegen den Anbieter. Für den Fall, dass die Nutzung der Website doch zu einem Vertragsverhältnis führen sollte, gilt rein vorsorglich nachfolgende Haftungsbeschränkung: Der Anbieter haftet für Vorsatz und grobe Fahrlässigkeit sowie bei Verletzung einer wesentlichen Vertragspflicht (Kardinalpflicht). Der Anbieter haftet unter Begrenzung auf Ersatz des bei Vertragsschluss vorhersehbaren vertragstypischen Schadens für solche Schäden, die auf einer leicht fahrlässigen Verletzung von Kardinalpflichten durch ihn oder eines seiner gesetzlichen Vertreter oder Erfüllungsgehilfen beruhen. Bei leicht fahrlässiger Verletzung von Nebenpflichten, die keine Kardinalpflichten sind, haftet der Anbieter nicht. Die Haftung für Schäden, die in den Schutzbereich einer vom Anbieter gegebenen Garantie oder Zusicherung fallen sowie die Haftung für Ansprüche aufgrund des Produkthaftungsgesetzes und Schäden aus der Verletzung des Lebens, des Körpers oder der Gesundheit bleibt hiervon unberührt.

(2) Urheberrecht

Die auf dieser Website veröffentlichten Inhalte und Werke sind urheberrechtlich geschützt. Jede vom deutschen Urheberrecht nicht zugelassene Verwertung bedarf der vorherigen schriftlichen Zustimmung des jeweiligen Autors oder Urhebers. Dies gilt insbesondere für Vervielfältigung, Bearbeitung, Übersetzung, Einspeicherung, Verarbeitung bzw. Wiedergabe von Inhalten in Datenbanken oder anderen elektronischen Medien und Systemen. Inhalte und Beiträge Dritter sind dabei als solche gekennzeichnet. Die unerlaubte Vervielfältigung oder Weitergabe einzelner Inhalte oder kompletter Seiten ist nicht gestattet und strafbar. Lediglich die Herstellung von Kopien und Downloads für den persönlichen, privaten und nicht kommerziellen Gebrauch ist erlaubt.

Links zur Website des Anbieters sind jederzeit willkommen und bedürfen keiner Zustimmung durch den Anbieter der Website. Die Darstellung dieser Website in fremden Frames ist nur mit Erlaubnis zulässig.

(3) Datenschutz

Durch den Besuch der Website des Anbieters können Informationen über den Zugriff (Datum, Uhrzeit, betrachtete Seite) auf dem Server gespeichert werden. Diese Daten gehören nicht zu den personenbezogenen Daten, sondern sind anonymisiert. Sie werden ausschließlich zu statistischen Zwecken ausgewertet. Eine Weitergabe an Dritte, zu kommerziellen oder nichtkommerziellen Zwecken, findet nicht statt.

Der Anbieter weist ausdrücklich darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen und nicht lückenlos vor dem Zugriff durch Dritte geschützt werden kann.

Die Verwendung der Kontaktdaten der Anbieterkennzeichnung - insbesondere der Telefon-/Faxnummern und E-Mailadresse - zur gewerblichen Werbung ist ausdrücklich nicht erwünscht, es sei denn der Anbieter hatte zuvor seine schriftliche Einwilligung erteilt oder es besteht bereits ein geschäftlicher Kontakt. Der Anbieter und alle auf dieser Website genannten Personen widersprechen hiermit jeder kommerziellen Verwendung und Weitergabe ihrer Daten.

(4) Anwendbares Recht

Es gilt ausschließlich das maßgebliche Recht der Bundesrepublik Deutschland.

(5) Besondere Nutzungsbedingungen

Soweit besondere Bedingungen für einzelne Nutzungen dieser Website von den vorgenannten Punkten (1) bis (4) abweichen, wird an entsprechender Stelle ausdrücklich darauf hingewiesen. In diesem Falle gelten im jeweiligen Einzelfall die besonderen Nutzungsbedingungen.

Quelle: Disclaimer von Juraforum.de - Portal mit Rechtsanwalt-Suche.