Heim Java JavaBase Was ist ein Java-Proxy?

Was ist ein Java-Proxy?

Nov 13, 2019 am 11:37 AM
java 代理

Was ist ein Java-Proxy?

Was ist ein Java-Proxy?

Was ist ein Proxy? Der Zugriff auf das Ziel erfolgt nicht direkt, sondern über eine Zwischenschicht, wie folgt:

Was ist ein Java-Proxy?

Statischer Java-Proxy

Wenn beispielsweise einige unserer Früchte, wie Bananen, Äpfel usw., in Java-Code geschrieben sind, sehen sie wahrscheinlich so aus:

(Empfohlenes Tutorial: Java-Tutorial )

//Fruit.java/**
 * 水果的接口
 */public interface Fruit {    /**
     * 获取水果的名字
     */
    public String getName();
}//Apple.javapublic class Apple implements Fruit {    @Override
    public String getName() {        return "苹果";
    }
}//Banana.javapublic class Banana implements Fruit {    @Override
    public String getName() {        return "香蕉";
    }
}
Nach dem Login kopieren

Um Obst zu essen, muss man es schälen. Man kann nicht für jede Frucht eine Unterklasse schreiben. Deshalb können wir ein Mittel herstellen und den Apfel schälen, bevor wir ihn essen. Wickeln Sie die ursprüngliche Frucht wie folgt in eine Schicht:


//PeelFruitProxy.java/**
 * 代理,让每个水果去皮
 */public class PeelFruitProxy implements Fruit {    private Fruit mFruit;    public PeelFruit(Fruit fruit) {        this.mFruit = fruit;
    }    @Override
    public String getName() {
        System.out.println("proxt:" + proxy.getClass().getName());        return "去皮的" + mFruit.getName();
    }
}
Nach dem Login kopieren

Fügen Sie eine Testklasse hinzu. Die Testklasse lautet wie folgt:

//Main.javapublic class Main {    public static void main(String[] args) {
        Apple apple=new Apple();//原始的苹果
        Banana banana=new Banana();//原始的香蕉

        PeelFruitProxy peelApple=new PeelFruitProxy(apple);//代理,添加去皮功能
        PeelFruitProxy peelBanana=new PeelFruitProxy(banana);//代理,添加去皮功能
        System.out.println(peelApple.getName());
        System.out.println(peelBanana.getName());
    }
}
Nach dem Login kopieren

Das Obige ist der statische Proxy von Java Vereinfacht ausgedrückt bedeutet das, das ursprüngliche Zielobjekt mit einer Ebene zu umhüllen, neue Dinge hinzuzufügen und dann das Ziel selbst aufzurufen. Aber wenn es sich nur um einen solchen statischen Proxy handelt, erfordert eine Schnittstelle einen Proxy, und ist die Implementierung sehr umständlich?

Dynamischer Proxy von Java

In Java gibt es eine Klasse namens Proxy, die dies erledigt, und Sie können Reflektion und Proxy-Abfangen direkt verwenden. Lassen Sie uns diese Klasse zunächst kurz vorstellen. Tatsächlich ist die am häufigsten verwendete statische Methode Proxt.newProxyInstance(), die so aussieht:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Nach dem Login kopieren

Zuerst müssen wir InvocationHandler implementieren, die Invoke-Methode implementieren und aufrufen Zum Zeitpunkt des Zielobjekts wird die Aufrufmethode zuerst aufgerufen, und der Implementierer muss die aufgerufene Methode in dieser Methode aktiv aufrufen.

//FruitInvocationHandler.java/**
 * 调用方法拦截器
 */public class FruitInvocationHandler implements InvocationHandler {    private Fruit mFruit;    public FruitInvocationHandler(Fruit fruit) {        this.mFruit = fruit;
    }    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String result = (String) method.invoke(mFruit, args);//需要在这个方法里面,主动调用被代理的对象。
        return "去皮的" + result;
    }
}
Nach dem Login kopieren

Führen Sie es aus:

//Main.Javapublic class Main {    public static void main(String[] args) {
        Apple apple = new Apple();
        Fruit proxyApple = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(apple));
        System.out.println(proxyApple.getClass().getName());
        System.out.println(proxyApple.getName());

        Banana banana = new Banana();
        Fruit proxyBanana = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(banana));
        System.out.println(proxyApple.getClass().getName());
        System.out.println(proxyBanana.getName());
    }
}
Nach dem Login kopieren

Was ist ein Java-Proxy?

Diese Methode dient dazu, einen PeelFruitProxy wie oben erwähnt zu generieren (der Name, den wir sehen, ist natürlich: com.sun ). Proxy.$Proxy0) wird dynamisch generiert, um zu vermeiden, dass es jedes Mal geschrieben werden muss. Dies ist auch der Grund, warum es als dynamischer Proxy bezeichnet wird, da wir jede Klasse zur Laufzeit vertreten können. AOP ist in vielen Programmen auf diese Weise implementiert, aber wir haben einige Merkmale gefunden. Der zweite Parameter von newProxyInstance() ist eine Liste von Schnittstellen.

Da unsere dynamisch generierte Proxy-Klasse auch eine Schnittstelle implementieren muss, damit sie leicht nach unten transformiert und ihre Methoden verwendet werden kann, hat die generierte Klasse sonst einen Klassennamen wie com.sun.proxy.$ Da sich Proxy0 im Speicher befindet, kann die generierte Methode nicht aufgerufen werden. ** Daher weist diese dynamische Proxy-Methode einen schwerwiegenden Mangel auf, nämlich dass die Proxy-Klasse die Schnittstelle implementieren muss. **

CGLib-Proxy

cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime.
Nach dem Login kopieren

Eine weitere bekannte Java-Proxy-Implementierung ist CGLib (Code Generation Library), ein auf ASM basierendes Codegenerierungs-Framework, das Sie verwenden können Um Klassen dynamisch zu generieren und dann das Abfangen von Methoden zu implementieren, können Sie das Problem des dynamischen Proxys von JDK vermeiden, bei dem die Zielklasse die Schnittstelle implementieren muss. Mit anderen Worten: CGLib kann zum Generieren des oben erwähnten PeelFruitProxy verwendet werden.

Lassen Sie mich kurz vorstellen, wie man es verwendet. Diese CGLib ist eine Bibliothek eines Drittanbieters. Wir müssen uns darauf verlassen:

compile 'cglib:cglib:3.2.8 '


Die neueste Version ist hier zu sehen (neue Version) [https://github.com/cglib/cglib/releases] Dann probieren wir es aus und implementieren den oben genannten Agenten

//FruitMethodInterceptor.java/**
 * CGLib代理的方法拦截器
 */public class FruitMethodInterceptor implements MethodInterceptor{    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String result = (String) proxy.invokeSuper(obj, args);//主要,这里调用的是父类,也就是说, 生成的类和原始类是继承关系
        return "去皮的"+result;
    }
}//Main.javapublic class Main {    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Apple.class);
        enhancer.setCallback(new FruitMethodInterceptor());
        Apple apple = (Apple) enhancer.create();
        System.out.println(apple.getClass().getName());
        System.out.println(apple.getName());
    }
}
Nach dem Login kopieren

run Der Effekt ist wie folgt:

Was ist ein Java-Proxy?

Wir sehen, dass die gleiche Funktion implementiert ist, aber Apple ist nicht mehr die ursprüngliche Apple-Klasse, sondern com .zjiecode.learn.java. Proxy.Apple$$EnhancerByCGLIB$$44ade224, ja, wir verwenden tatsächlich diese Klasse, nicht die ursprüngliche Apple-Klasse, und implementiert schließlich den Proxy für die Apple-Klasse. Da die Vererbung verwendet wird, ist es auf diese Weise nicht erforderlich, dass die Proxy-Klasse die Schnittstelle implementiert. Natürlich kann er Agenten auch über Schnittstellen implementieren.

Zusammenfassung

Der erste Proxy-Typ wird hier nicht erwähnt. Er ist nur für einen einzelnen Schnittstellen-Proxy geeignet und wird zur Kompilierungszeit festgelegt.

Die zweite und dritte Art von Proxys sind alle dynamische Proxys, aber wir sehen, dass es Unterschiede gibt:

1) Der dynamische Proxy von JDK kann nur Schnittstellen-Proxys implementieren und ist ein gepacktes Proxy-Objekt (. Das heißt, während des Proxy-Prozesses gibt es zwei Objekte, ein Proxy-Objekt und ein Zielobjekt. Das Zielobjekt wird in das Proxy-Objekt gepackt.

2) Der Proxy von CGLib erbt das Zielobjekt, generiert eine neue Klasse und implementiert dann den Proxy. Auf diese Weise befindet sich ein Proxyobjekt im Speicher und es wird keine direkte Vererbung verwendet Methode

generiert Proxy-Klassen zur Laufzeit, was sich von Javapoet unterscheidet, das Klassen zur Kompilierungszeit generiert.

Das obige ist der detaillierte Inhalt vonWas ist ein Java-Proxy?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
4 Wochen 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.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

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

See all articles