Lassen Sie uns zunächst vorstellen, was ein Agent ist.
(Lernvideo-Sharing: Java-Video-Tutorial)
Proxy ist ein Entwurfsmuster, dessen Kernidee darin besteht, den Zugriff auf das Ziel auf das Proxy-Objekt zu übertragen. Dies hat den Vorteil, dass das Zielobjekt über das Proxy-Objekt einige zusätzliche Funktionen hinzufügen kann, ohne den Code zu ändern. Hierbei handelt es sich um eine Programmieridee, die durch Agenten einige erweiterte Funktionen hinzufügt, ohne den ursprünglichen Code zu ändern.
Der Proxy-Prozess ist wie in der Abbildung dargestellt. Der Benutzer greift auf das Proxy-Objekt zu, und das Proxy-Objekt erreicht den Zweck des Benutzers, auf das Zielobjekt zuzugreifen.
Der Proxy-Modus umfasst Folgendes Drei Rollen:
ISubject: Schnittstellenobjekt. Diese Schnittstelle ist die Schnittstelle, die vom Objekt und seinem Proxy gemeinsam genutzt wird.
TargetSubject: Das Zielobjekt ist eine Klasse, die die abstrakte Themenschnittstelle implementiert.
Proxy: Proxy-Rolle, die einen Verweis auf das Zielobjekt TargetSubject enthält, sodass das reale Objekt manipuliert werden kann. Das Proxy-Objekt stellt dieselbe Schnittstelle wie das Zielobjekt bereit, sodass es das Zielobjekt jederzeit ersetzen kann. Gleichzeitig kann das Proxy-Objekt andere Operationen hinzufügen, wenn es Operationen am Zielobjekt ausführt, was der Kapselung des realen Objekts entspricht.
Allgemeine Proxy-Modi sind in statischen Proxy und dynamischen Proxy unterteilt. Die Implementierung des dynamischen Proxys in Java ist in dynamischen JDK-Proxy und cglib-Proxy unterteilt.
Statischer Proxy
Wie bereits erwähnt, gibt es im Proxy-Modus drei Rollen: eine ist die Zielschnittstelle, die zweite das Zielobjekt und die dritte das Proxy-Objekt.
Jetzt wird es mit spezifischem Code implementiert. Zuerst lautet die Zielschnittstelle wie folgt:
public interface IBlogService { void writeBlog(); }
Das Zielobjekt implementiert die Zielschnittstelle, der Code lautet wie folgt:
public class BlogService implements IBlogService { @Override public void writeBlog() { System.out.println("i'm writing..."); } }
Statisches Proxy-Objekt, das Zielobjekt wird über das erhalten Konstruktormethode und die Zielschnittstelle werden in der Methode der Zielschnittstelle aufgerufen. Der Code lautet wie folgt:
public class BlogStaticProxy implements IBlogService{ private IBlogService blogService; public BlogStaticProxy(IBlogService blogService) { this.blogService = blogService; } @Override public void writeBlog() { System.out.println("start writing..."); blogService.writeBlog(); System.out.println("end writing..."); } }
Das statische Proxy-Objekt erhält das Zielobjekt über die Konstruktionsmethode Zielschnittstelle. Die Methode des Zielobjekts wird in der Methode der Zielschnittstelle aufgerufen. Der Code lautet wie folgt:
public class BlogStaticProxy implements IBlogService{ private IBlogService blogService; public BlogStaticProxy(IBlogService blogService) { this.blogService = blogService; } @Override public void writeBlog() { System.out.println("start writing..."); blogService.writeBlog(); System.out.println("end writing..."); } }
Statischer Proxy, ohne das Zielobjekt zu ändern, können Sie das Proxy-Objekt verwenden, um weitere auszuführen Erweiterungsfunktionen. Statische Methoden sind jedoch nicht sehr flexibel. Wenn der Code der Zielschnittstelle geändert wird, müssen sowohl das Zielobjekt als auch das Proxy-Objekt geändert werden.
Der dynamische Proxy vermeidet diese Situation bis zu einem gewissen Grad. Der dynamische Proxy erfordert kein Proxy-Objekt, um die Zielschnittstelle zu implementieren, und das Proxy-Objekt wird dynamisch im Speicher der Java Virtual Machine generiert.
Dynamisches Jdk-Objekt Proxy wird von Proxy gesteuert. Diese Klasse wird generiert und verfügt über drei Parameter:
ClassLoader-Loader: Gibt das aktuelle Zielobjekt für die Verwendung des Klassenladers an. Die Methode zum Abrufen des Loaders ist festgelegt.
Class>[]-Schnittstellen ,: Die vom Zielobjekttyp implementierte Schnittstelle, verwenden Sie eine generische Methode, um den Typ zu bestätigen
InvocationHandler h: Ereignisverarbeitung: Wenn die Methode des Zielobjekts ausgeführt wird, wird die Methode des Ereignishandlers ausgelöst und die Methode des Das aktuell ausgeführte Zielobjekt wird als Parameter übergeben
public class TestStaticProxy { public static void main(String[] args) { IBlogService target = new BlogService(); BlogStaticProxy proxy = new BlogStaticProxy(target); proxy.write(); } }
Jdks Dynamik Der Proxy-Code lautet wie folgt:
start writing… i’m writing… end writing…
Testklasse:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { }
Die Konsole druckt wie folgt:
public class JdkBlogProxyFactory { private Object target; public JdkBlogProxyFactory(Object target) { this.target = target; } public Object newInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("start writing"); Object o = method.invoke(target, args); System.out.println("end writing"); return o; }); } }
CGLib dynamischer Proxy
CGLib verwendet sehr niedrig- Das Prinzip der Bytecode-Technologie auf Ebene besteht darin, mithilfe der Bytecode-Technologie eine untergeordnete Klasse für eine Klasse zu erstellen und in der Unterklasse die Methodenabfangtechnologie zu verwenden, um alle Methodenaufrufe der übergeordneten Klasse abzufangen und entsprechende übergreifende Logik einzubinden. Die Proxy-Factory-Klasse von
CglibBlogFactory lautet wie folgt:
public class TestJdkProxy { public static void main(String[] args) { IBlogService target = new BlogService(); System.out.println(target.getClass()); // 给目标对象,创建代理对象 IBlogService proxy = (IBlogService) new JdkBlogProxyFactory(target).newInstance(); // class $Proxy0 内存中动态生成的代理对象 System.out.println(proxy.getClass()); // 执行方法 【代理对象】 proxy.writeBlog(); } }
Testklasse:
class com.forezp.proxy.BlogService class com.sun.proxy.$Proxy0 start writing i'm writing... end writing
Laufendes Programm, Konsolendruck:
public class CglibBlogFactory implements MethodInterceptor { private Object target; public CglibBlogFactory(Object target) { this.target = target; } //给目标对象创建一个代理对象 public Object getProxyInstance() { //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("start writing..."); //执行目标对象的方法 Object returnValue = method.invoke(target, objects); System.out.println("end writing..."); return returnValue; } }
Verwandte Empfehlungen:
Java-Einführungs-TutorialDas obige ist der detaillierte Inhalt vonEinführung in den Java-Proxy-Modus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!