Heim Java javaLernprogramm Vertiefendes Verständnis des dynamischen Java-Proxys

Vertiefendes Verständnis des dynamischen Java-Proxys

Feb 08, 2017 am 11:00 AM
java 代理

Dynamischer Proxy von JAVA
Agent-Modus
Der Proxy-Modus ist ein häufig verwendetes Java-Entwurfsmuster. Sein Merkmal besteht darin, dass die Proxy-Klasse und die Delegate-Klasse dieselbe Schnittstelle haben. Die Proxy-Klasse ist hauptsächlich für die Vorverarbeitung von Nachrichten verantwortlich und Filtern für die Delegatklasse-Nachricht, Weiterleiten der Nachricht an die Delegatenklasse und anschließendes Verarbeiten der Nachricht usw. Normalerweise besteht eine Assoziation zwischen einer Proxy-Klasse und einer Delegate-Klasse. Das Objekt der Proxy-Klasse selbst implementiert den Dienst nicht, sondern durch den Aufruf der entsprechenden Methoden des Objekts der Delegate-Klasse bestimmte Dienste bereitstellen.
Je nach Erstellungszeitraum des Agenten können Agentenklassen in zwei Typen unterteilt werden.
Statischer Proxy: Von Programmierern erstellt oder automatisch von bestimmten Tools generiert und dann kompiliert. Bevor das Programm ausgeführt wird, ist die .class-Datei der Proxy-Klasse bereits vorhanden.
Dynamischer Proxy: Wird mithilfe des Reflexionsmechanismus dynamisch erstellt, wenn das Programm ausgeführt wird.

Erster Blick auf den statischen Proxy:

1. Count.java

package net.battier.dao;  
  
/** 
 * 定义一个账户接口 
 *  
 * @author Administrator 
 *  
 */  
public interface Count {  
    // 查看账户方法  
    public void queryCount();  
  
    // 修改账户方法  
    public void updateCount();  
  
}
Nach dem Login kopieren

2. CountImpl.java

package net.battier.dao.impl;  
  
import net.battier.dao.Count;  
  
/** 
 * 委托类(包含业务逻辑) 
 *  
 * @author Administrator 
 *  
 */  
public class CountImpl implements Count {  
  
    @Override  
    public void queryCount() {  
        System.out.println("查看账户方法...");  
  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("修改账户方法...");  
  
    }  
  
}  
  
、CountProxy.java  
package net.battier.dao.impl;  
  
import net.battier.dao.Count;  
  
/** 
 * 这是一个代理类(增强CountImpl实现类) 
 *  
 * @author Administrator 
 *  
 */  
public class CountProxy implements Count {  
    private CountImpl countImpl;  
  
    /** 
     * 覆盖默认构造器 
     *  
     * @param countImpl 
     */  
    public CountProxy(CountImpl countImpl) {  
        this.countImpl = countImpl;  
    }  
  
    @Override  
    public void queryCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.queryCount();  
        System.out.println("事务处理之后");  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.updateCount();  
        System.out.println("事务处理之后");  
  
    }  
  
}
Nach dem Login kopieren

3. TestCount.java

package net.battier.test;  
  
import net.battier.dao.impl.CountImpl;  
import net.battier.dao.impl.CountProxy;  
  
/** 
 *测试Count类 
 *  
 * @author Administrator 
 *  
 */  
public class TestCount {  
    public static void main(String[] args) {  
        CountImpl countImpl = new CountImpl();  
        CountProxy countProxy = new CountProxy(countImpl);  
        countProxy.updateCount();  
        countProxy.queryCount();  
  
    }  
}
Nach dem Login kopieren

Wenn Sie den Code beobachten, können Sie feststellen, dass jede Proxy-Klasse nur eine Schnittstelle bedienen kann. Auf diese Weise werden während der Programmentwicklung zwangsläufig zu viele Proxys generiert alle Proxys Mit Ausnahme der aufgerufenen Methode sind alle anderen Vorgänge gleich, daher muss der Code zu diesem Zeitpunkt wiederholt werden. Der beste Weg, dieses Problem zu lösen, besteht darin, eine Proxy-Klasse zum Abschließen aller Proxy-Funktionen zu verwenden. In diesem Fall muss ein dynamischer Proxy zum Abschließen verwendet werden.
Werfen wir einen Blick auf den dynamischen Proxy:
Der dynamische JDK-Proxy enthält eine Klasse und eine Schnittstelle:
InvocationHandler-Schnittstelle:

public interface InvocationHandler { 
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 
}
Nach dem Login kopieren

Parameterbeschreibung:
Objekt-Proxy: verweist zum Proxy-Objekt.
Methodenmethode: die aufzurufende Methode
Objekt[]-Argumente: die beim Aufruf der Methode erforderlichen Parameter

Sie können sich die Unterklasse der InvocationHandler-Schnittstelle als die letzte Operationsklasse eines Proxys vorstellen. ersetzt ProxySubject .

Proxy-Klasse:
Die Proxy-Klasse ist eine auf Proxy-Operationen spezialisierte Klasse, die über diese Klasse dynamisch für eine oder mehrere Schnittstellen generiert werden kann:
öffentliches statisches Objekt newProxyInstance(ClassLoader-Loader, Class[]-Schnittstellen,
InvocationHandler h)
 🎜>ClassInvocationHandler h: die Unterklasse abrufen Instanz der InvocationHandler-Schnittstelle

Ps: Klassenlader
Eine ClassLoader-Klasse ist in der newProxyInstance()-Methode in der Proxy-Klasse erforderlich. Instanzen von ClassLoader entsprechen tatsächlich Klassenladern. In Java gibt es drei Hauptklassenlader ;

Booststrap ClassLoader: Dieser Loader ist in C++ geschrieben und kann in der allgemeinen Entwicklung nicht angezeigt werden;

Erweiterung ClassLoader: wird zum Laden erweiterter Klassen verwendet, die im Allgemeinen den Klassen im jrelibext-Verzeichnis entsprechen; ) lädt die durch den Klassenpfad angegebene Klasse, den am häufigsten verwendeten Lader.

Dynamischer Proxy
Im Gegensatz zur statischen Proxy-Klasse wird der Bytecode der dynamischen Proxy-Klasse dynamisch durch den Java-Reflektionsmechanismus generiert, wenn das Programm ausgeführt wird, ohne dass Programmierer dies tun müssen Schreiben Sie den Quellcode manuell. Dynamische Proxy-Klassen vereinfachen nicht nur die Programmierarbeit, sondern verbessern auch die Skalierbarkeit von Softwaresystemen, da der Java-Reflexionsmechanismus jede Art von dynamischen Proxy-Klassen generieren kann. Die Proxy-Klasse und die InvocationHandler-Schnittstelle im Paket java.lang.reflect bieten die Möglichkeit, dynamische Proxy-Klassen zu generieren.

Dynamisches Proxy-Beispiel:


1. BookFacadeImpl.java

3 🎜>

Der dynamische Proxy von JDK basiert jedoch auf der Schnittstellenimplementierung. Wenn einige Klassen die Schnittstelle nicht implementieren, kann der JDK-Proxy nicht verwendet werden, daher muss der dynamische Proxy von cglib verwendet werden.
package net.battier.dao;  
  
public interface BookFacade {  
    public void addBook();  
}
Nach dem Login kopieren
Nach dem Login kopieren

Dynamischer Proxy von Cglib

Der dynamische Proxy-Mechanismus von JDK kann nur Proxy-Klassen implementieren, die keine Schnittstellen implementieren können. Der dynamische Proxy von JDK kann nicht implementiert werden. Das Prinzip besteht darin, eine Unterklasse für zu generieren die angegebene Zielklasse und überschreiben Sie die Methoden, um eine Erweiterung zu erreichen. Da jedoch Vererbung verwendet wird, kann die endgültige geänderte Klasse nicht als Proxy verwendet werden.
package net.battier.dao.impl;  
  
import net.battier.dao.BookFacade;  
  
public class BookFacadeImpl implements BookFacade {  
  
    @Override  
    public void addBook() {  
        System.out.println("增加图书方法。。。");  
    }  
  
}  
  
、BookFacadeProxy.java  
  
package net.battier.proxy;  
  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
  
/** 
 * JDK动态代理代理类 
 *  
 * @author student 
 *  
 */  
public class BookFacadeProxy implements InvocationHandler {  
    private Object target;  
    /** 
     * 绑定委托对象并返回一个代理类 
     * @param target 
     * @return 
     */  
    public Object bind(Object target) {  
        this.target = target;  
        //取得代理对象  
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)  
    }  
  
    @Override  
    /** 
     * 调用方法 
     */  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object result=null;  
        System.out.println("事物开始");  
        //执行方法  
        result=method.invoke(target, args);  
        System.out.println("事物结束");  
        return result;  
    }  
  
}
Nach dem Login kopieren
Beispiel

1. BookFacadeCglib.java
package net.battier.test;  
  
import net.battier.dao.BookFacade;  
import net.battier.dao.impl.BookFacadeImpl;  
import net.battier.proxy.BookFacadeProxy;  
  
public class TestProxy {  
  
    public static void main(String[] args) {  
        BookFacadeProxy proxy = new BookFacadeProxy();  
        BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
        bookProxy.addBook();  
    }  
  
}
Nach dem Login kopieren

2. BookCadeImpl1.java



3. BookFacadeProxy.java

4. TestCglib.java
package net.battier.dao;  
  
public interface BookFacade {  
    public void addBook();  
}
Nach dem Login kopieren
Nach dem Login kopieren

Für ein tieferes Verständnis der Artikel zum Thema Java Dynamic Proxy beachten Sie bitte die chinesische PHP-Website!
package net.battier.dao.impl;  
  
/** 
 * 这个是没有实现接口的实现类 
 *  
 * @author student 
 *  
 */  
public class BookFacadeImpl1 {  
    public void addBook() {  
        System.out.println("增加图书的普通方法...");  
    }  
}
Nach dem Login kopieren
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Feb 07, 2025 pm 12:11 PM

Spring Boot vereinfacht die Schaffung robuster, skalierbarer und produktionsbereiteter Java-Anwendungen, wodurch die Java-Entwicklung revolutioniert wird. Der Ansatz "Übereinkommen über Konfiguration", der dem Feder -Ökosystem inhärent ist, minimiert das manuelle Setup, Allo

See all articles