Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung des statischen, dynamischen Proxys und des dynamischen CGLIB-Proxys in Java (Bild)

Detaillierte Erläuterung des statischen, dynamischen Proxys und des dynamischen CGLIB-Proxys in Java (Bild)

黄舟
黄舟Original
2017-08-08 10:02:171434Durchsuche

In diesem Artikel werden hauptsächlich statische Proxys, dynamische Proxys und CGLIB-Dynamik-Proxy-Zusammenfassungen in JAVA vorgestellt. Interessierte können sich darüber informieren.

Der Proxy-Modus ist das am häufigsten verwendete Design in Java Eines der Muster, das besonders häufig im Spring Framework verwendet wird. Der Proxy-Modus von Java kann im Allgemeinen in statischen Proxy, dynamischen Proxy und dynamischen CGLIB-Proxy unterteilt werden.

Die oben genannten drei Proxy-Modi werden separat erläutert.

1. Statischer Proxy

Statischer Proxy bedeutet eigentlich, die Proxy-Klasse der Proxy-Methode im Voraus zu schreiben, bevor das Programm ausgeführt wird, und sie dann nach der Kompilierung auszuführen. Die Klasse existiert bereits, bevor das Programm ausgeführt wird.
Nachfolgend implementieren wir eine statische Proxy-Demo:

Statischer Proxy

Definieren Sie ein Schnittstellenziel


package com.test.proxy;

public interface Target {

  public String execute();
}

TargetImpl implementiert die Schnittstelle Target


package com.test.proxy;

public class TargetImpl implements Target {

  @Override
  public String execute() {
    System.out.println("TargetImpl execute!");
    return "execute";
  }
}

Proxy-Klasse


package com.test.proxy;

public class Proxy implements Target{

  private Target target;

  public Proxy(Target target) {
    this.target = target;
  }

  @Override
  public String execute() {
    System.out.println("perProcess");
    String result = this.target.execute();
    System.out.println("postProcess");
    return result;
  }
}

Testklasse:


package com.test.proxy;

public class ProxyTest {

  public static void main(String[] args) {

    Target target = new TargetImpl();
    Proxy p = new Proxy(target);
    String result = p.execute();
    System.out.println(result);
  }

}

Laufendes Ergebnis:


perProcess
TargetImpl execute!
postProcess
execute

Statischer Proxy muss spezifisch sein zum Proxy Die Proxy-Klasse muss im Voraus geschrieben werden. Wenn es viele Proxy-Methoden gibt, muss viel Code geschrieben werden. Daher werden die oben genannten Mängel durch dynamische Proxys ausgeglichen.

2. Dynamischer Proxy

Dynamischer Proxy verwendet hauptsächlich den Reflexionsmechanismus, um die erforderliche Proxy-Klasse zur Laufzeit dynamisch zu generieren.

Dynamischer Proxy

Schnittstelle


package com.test.dynamic;

public interface Target {

  public String execute();
}

Implementierungsklasse


package com.test.dynamic;

public class TargetImpl implements Target {

  @Override
  public String execute() {
    System.out.println("TargetImpl execute!");
    return "execute";
  }
}

Proxy-Klasse


package com.test.dynamic;


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

public class DynamicProxyHandler implements InvocationHandler{

  private Target target;

  public DynamicProxyHandler(Target target) {
    this.target = target;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("========before==========");
    Object result = method.invoke(target,args);
    System.out.println("========after===========");
    return result;
  }
}

Testklasse


package com.test.dynamic;

import java.lang.reflect.Proxy;

public class DynamicProxyTest {

  public static void main(String[] args) {
    Target target = new TargetImpl();
    DynamicProxyHandler handler = new DynamicProxyHandler(target);
    Target proxySubject = (Target) Proxy.newProxyInstance(TargetImpl.class.getClassLoader(),TargetImpl.class.getInterfaces(),handler);
    String result = proxySubject.execute();
    System.out.println(result);
  }

}

Laufergebnisse:


========before==========
TargetImpl execute!
========after===========
execute

Unabhängig davon, ob es sich um einen dynamischen Proxy oder einen statischen Leader handelt, muss eine Schnittstelle definiert werden, bevor die Proxy-Funktion implementiert werden kann. Dies weist jedoch auch Einschränkungen auf. Um dieses Problem zu lösen, wurde eine dritte Proxy-Methode entwickelt: cglib-Proxy.

3.cglib-Proxy

CGLib verwendet eine Bytecode-Technologie auf sehr niedriger Ebene. Das Prinzip besteht darin, eine Unterklasse für eine Klasse mithilfe der Bytecode-Technologie und der Methodenabfangtechnologie zu erstellen wird in Unterklassen verwendet, um alle Aufrufe von Methoden der übergeordneten Klasse abzufangen und entsprechend übergreifende Logik einzubinden. Sowohl der dynamische JDK-Proxy als auch der dynamische CGLib-Proxy bilden die Grundlage für die Implementierung von Spring AOP.

cglib dynamischer Proxy

Zielklasse


package com.test.cglib;

public class Target {

  public String execute() {
    String message = "-----------test------------";
    System.out.println(message);
    return message;
  }
}

Generische Proxy-Klasse :


package com.test.cglib;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor{

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    System.out.println(">>>>MethodInterceptor start...");
    Object result = proxy.invokeSuper(obj,args);
    System.out.println(">>>>MethodInterceptor ending...");
    return "result";
  }
}

Testklasse


package com.test.cglib;

import net.sf.cglib.proxy.Enhancer;

public class CglibTest {

  public static void main(String ... args) {
    System.out.println("***************");
    Target target = new Target();
    CglibTest test = new CglibTest();
    Target proxyTarget = (Target) test.createProxy(Target.class);
    String res = proxyTarget.execute();
    System.out.println(res);
  }

  public Object createProxy(Class targetClass) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(targetClass);
    enhancer.setCallback(new MyMethodInterceptor());
    return enhancer.create();
  }

}

Ausführungsergebnis:


***************
>>>>MethodInterceptor start...
-----------test------------
>>>>MethodInterceptor ending...
result

Der Generierungsprozess des Proxy-Objekts wird von der Enhancer-Klasse implementiert. Die ungefähren Schritte sind wie folgt:

1. Generieren Sie den binären Bytecode der Proxy-Klasse Klasse;

2. Laden Sie den binären Bytecode über Class.forName, um ein Klassenobjekt zu generieren.

3 Klassenobjekt.

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des statischen, dynamischen Proxys und des dynamischen CGLIB-Proxys in Java (Bild). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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