Heim  >  Artikel  >  Java  >  Detaillierte Analyse des Java-Proxy-Modus (Bild und Text)

Detaillierte Analyse des Java-Proxy-Modus (Bild und Text)

黄舟
黄舟Original
2017-03-22 10:19:541179Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen zum JavaProxy-Modus vor. Er hat einen bestimmten Referenzwert.

Der Proxy-Modus ist einer der am häufigsten verwendeten Entwurfsmuster. Die neue Idee besteht darin, ein Proxy-Objekt zwischen dem eigentlichen Objekt und dem Aufrufer einzufügen, um zusätzliche Verarbeitung oder andere Operationen bereitzustellen. Diese zusätzlichen Vorgänge erfordern normalerweise eine Kommunikation mit dem tatsächlichen Objekt. Die am Proxy-Muster beteiligten Rollen sind im Allgemeinen:

Abstrakte Rolle: Deklariert die gemeinsame Schnittstelle des realen Objekts und des Proxy-Objekts 🎜>
Proxy-Rolle: Die Proxy-Objektrolle enthält intern einen Verweis auf das reale Objekt, sodass das reale Objekt manipuliert werden kann. Gleichzeitig stellt das Proxy-Objekt dieselbe Schnittstelle wie das reale Objekt bereit, sodass es manipuliert werden kann Ersetzen Sie das reale Objekt jederzeit. Gleichzeitig kann das Proxy-Objekt andere Operationen hinzufügen, wenn es Operationen am realen Objekt ausführt, was einer Kapselung des realen Objekts entspricht.


Echte Rolle: Das durch die Proxy-Rolle dargestellte reale Objekt ist das Objekt, auf das wir letztendlich verweisen möchten.


Im Folgenden wird das

Senden einer Nachricht

als Beispiel genommen, um die grundlegende Implementierung eines einfachen Proxy-Modus zu veranschaulichen:
Klären Sie zunächst den Zweck: dort ist eine Nachricht, die benötigt wird. Um diese Nachricht zu versenden, definieren Sie die entsprechende Schnittstelle MessageHandler entsprechend diesem Zweck. Zusätzliche Vorgänge erforderlich: Angenommen, wir müssen überprüfen, ob die Länge der Nachricht die angegebene Länge nicht überschreiten und nicht leer sein darf, und wir müssen zählen, wie oft relevante Informationen gesendet werden. Wenn die Anzahl die angegebene Anzahl überschreitet, müssen wir dies tun eine Warnung ausgeben. Wir implementieren diesen zusätzlichen Vorgang über das Proxy-Muster. Im Folgenden finden Sie das entsprechende Klassendiagramm und den Beispielcode.



Im Beispiel können wir während des Nachrichtenversandprozesses problemlos verschiedene erforderliche zusätzliche Verarbeitungsmethoden hinzufügen. und kann auch die Art und Weise, wie Nachrichten verarbeitet werden, bequem ersetzen, z. B. das Versenden von Nachrichten per E-Mail durch das Versenden von Nachrichten per SMS ersetzen, ohne dass der Anrufer davon überhaupt etwas mitbekommt! Proxys sind immer dann sehr nützlich, wenn Sie einige zusätzliche Operationen von einem bestimmten Objekt trennen möchten, insbesondere wenn Sie Änderungen einfach vornehmen möchten oder wenn Sie einige zusätzliche Operationen einfügen möchten, bevor die Methode des bestimmten Objekts ausgeführt wird!
//接口定义  
public interface MessageHandler {  
public void sendMessage(String msg);  
}  
//通过Email方式发送消息的实现类  
public class EmailMessage implements MessageHandler {  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
System.out.println(msg+" send!!");  
}  
}  
//消息处理的代理类  
public class MessageProxy implements MessageHandler {  
private static int count;  
private MessageHandler emailMsg;  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
if(checkMessage(msg))  
{  
if(emailMsg==null) emailMsg=new EmailMessage();  
count++;  
emailMsg.sendMessage(msg);  
System.out.println("Message sent:"+count);  
}  
}  
private boolean checkMessage(String msg) {  
return msg != null && msg.length() > 10;  
}  
}  
//调用类  
public class MainClass {  
private static void runProxy(MessageHandler handler)  
{  
handler.sendMessage("message for test");  
}  
/** 
 * @param args 
 */  
public static void main(String[] args) {  
// TODO Auto-generated method stub  
runProxy(new EmailMessage());  
System.out.println("++++++++++++++++Pjroxy++++++++++++++++++");  
runProxy(new MessageProxy());  
}  
}  
//输出  
message for test send!!  
++++++++++++++++Pjroxy++++++++++++++++++  
message for test send!!  
Message sent:1


Dynamischer Proxy


Die Einführung des dynamischen Proxy-Mechanismus in Java hat die Idee des Proxy-Modells vollständiger und fortschrittlicher gemacht. Es ermöglicht die dynamische Erstellung von Proxys und unterstützt dynamische Aufrufe von Proxy-Methoden. Die dynamische Java-Proxy-Klasse befindet sich im Paket Java.

lang

.reflect, das im Allgemeinen die folgenden zwei Klassen umfasst:
(1): Diese Schnittstelle definiert nur Eine Methode

Object

: invoke(Object obj,Method method, Object[] args). Bei der tatsächlichen Verwendung bezieht sich der erste Parameter obj im Allgemeinen auf die Proxy-Klasse, method auf die Proxy-Methode, z. B. request () im obigen Beispiel, und args auf das Parameterarray der Methode. Diese abstrakte Methode wird dynamisch in der Proxy-Klasse implementiert.
(2).Proxy: Diese Klasse ist eine dynamische Proxy-Klasse. Ihre Funktion ähnelt dem ProxySubject im obigen Beispiel, das hauptsächlich den folgenden Inhalt enthält:

Protected Proxy(InvocationHandler h ):

Konstruktor
, wird voraussichtlich verwendet, um dem internen h einen Wert zuzuweisen. Statische Klasse getProxyClass (ClassLoader-Loader, Class[]-Schnittstellen): Ruft eine Proxy-Klasse ab, wobei Loader der Klassenlader und Interfaces ein Array aller Schnittstellen ist, die der realen Klasse gehören.

Statisches Objekt newProxyInstance(ClassLoader-Loader, Class[]-Schnittstellen, InvocationHandler h): Gibt eine Instanz der Proxy-Klasse zurück. Die zurückgegebene Proxy-Klasse kann als Proxy-Klasse verwendet werden (die Proxy-Klasse kann verwendete Methode, die in der Subject-Schnittstelle deklariert ist).


Der sogenannte dynamische Proxy ist eine Klasse: Es handelt sich um eine zur Laufzeit generierte Klasse. Beim Generieren müssen Sie eine Reihe von Schnittstellen bereitstellen, und dann erklärt die Klasse, dass sie diese implementiert Schnittstellen. Sie können Instanzen dieser Klasse natürlich als jede dieser Schnittstellen verwenden. Natürlich handelt es sich bei diesem dynamischen Proxy tatsächlich um einen Proxy. Er erledigt keine wesentliche Arbeit für Sie. Bei der Generierung seiner Instanz müssen Sie einen Handler bereitstellen, der die eigentliche Arbeit übernimmt. Lassen Sie uns das obige Beispiel des Sendens von Informationen über einen dynamischen Proxy erneut implementieren!


Basierend auf dem obigen Beispiel fügen wir zunächst eine Verarbeitungsklasse zum Versenden von Nachrichten per SMS hinzu:


public class SmsMessage implements MessageHandler {  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
System.out.println("SMS Message :" + msg+" sent !");  
}  
}  
//动态代理类  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
public class DynamicMessageProxy implements InvocationHandler {  
private static int count;  
private MessageHandler msgHandler;  
public DynamicMessageProxy(MessageHandler handler) {  
msgHandler = handler;  
}  
@Override  
public Object invoke(Object proxy, Method method, Object[] args)  
throws Throwable {  
// TODO Auto-generated method stub  
System.out.println("++++++++=============+++++++++");  
System.out.println("proxy:" + proxy.getClass());  
System.out.println("method:" + method);  
System.out.println("++++++++=============+++++++++");  
if (args != null && args.length == 1 && checkMessage((String) args[0])) {  
count++;  
System.out.println("Message sent:" + count);  
return method.invoke(msgHandler, args);  
}  
return null;  
}  
private boolean checkMessage(String msg) {  
return msg != null && msg.length() > 10;  
}  
}  
//下面是调用  
import java.lang.reflect.Proxy;  
public class MainClass {  
private static void runProxy(MessageHandler handler) {  
handler.sendMessage("message for test");  
}  
/** 
 * @param args 
 */  
public static void main(String[] args) {  
// TODO Auto-generated method stub  
// runProxy(new EmailMessage());  
// System.out.println("++++++++++++++++Proxy++++++++++++++++++");  
// runProxy(new MessageProxy());  
MessageHandler handler = new EmailMessage();  
runProxy(handler);  
MessageHandler proxy = (MessageHandler) Proxy.newProxyInstance(  
MessageHandler.class.getClassLoader(),  
new Class[] { MessageHandler.class }, new DynamicMessageProxy(  
handler));  
runProxy(proxy);  
System.out.println("++++++++++++++++++++++++++++++++++");  
// 短信方式  
handler = new SmsMessage();  
runProxy(handler);  
proxy = (MessageHandler) Proxy.newProxyInstance(MessageHandler.class  
.getClassLoader(), new Class[] { MessageHandler.class },  
new DynamicMessageProxy(handler));  
runProxy(proxy);  
}  
}  
//下面为以上方法的输出:  
message for test send!!  
++++++++=============+++++++++  
proxy:class $Proxy0  
method:public abstract void MessageHandler.sendMessage(java.lang.String)  
++++++++=============+++++++++  
Message sent:1  
message for test send!!  
++++++++++++++++++++++++++++++++++  
SMS Message :message for test sent !  
++++++++=============+++++++++  
proxy:class $Proxy0  
method:public abstract void MessageHandler.sendMessage(java.lang.String)  
++++++++=============+++++++++  
Message sent:2  
SMS Message :message for test sent !

 以上例子中,通过调用Proxy.newProxyInstance方法创建动态代理对象,该方法需要传入一个 类加载器、一组希望代理实现的接口列表、InvocationHandler 接口的一个具体实现。动态代理可以将所有调用重定向到调用处理器,通常我们会向该处理器传递一个时间对象的引用。invoke()方法中传递进来了代理对象,当你需要区分请求来源时这是非常有用的,例如你可以通过判断传入的方法名屏蔽掉某些方法的执行!动态代理机制并不是会很频繁使用的方法,它通常用来解决一些特定情况下的问题,因此不要盲目的为了使用而使用,要根据自己的实际需求来决定!

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse des Java-Proxy-Modus (Bild und Text). 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