ホームページ >Java >&#&チュートリアル >Java プロキシ モードの詳細な分析 (画像とテキスト)

Java プロキシ モードの詳細な分析 (画像とテキスト)

黄舟
黄舟オリジナル
2017-03-22 10:19:541231ブラウズ

この記事では、主に Javaプロキシ モードの関連情報を詳しく紹介します。興味のある方は参考にしてください。

プロキシ モードは、最も一般的に使用される

デザイン パターンの 1 つです。新しいアイデアは、追加の処理やさまざまな操作を提供するために、実際のオブジェクトと呼び出し元の間にプロキシ オブジェクトを挿入することです。これらの追加操作では、通常、実際のオブジェクトとの通信が必要です。一般に、プロキシ パターンに含まれるロールは次のとおりです。

抽象ロール: 実際のオブジェクトとプロキシ オブジェクトの共通インターフェイスを宣言します。


プロキシ ロール: プロキシ オブジェクトのロール。内部には実オブジェクトへの参照が含まれています。実オブジェクトを操作できるように、同時にプロキシ オブジェクトは実オブジェクトと同じインターフェイスを提供し、いつでも実オブジェクトを置き換えることができます。 。同時に、プロキシ オブジェクトは、実際のオブジェクトに対して操作を実行するときに他の操作を追加できます。これは、実際のオブジェクトをカプセル化することと同じです。


実際のロール: プロキシ ロールによって表される実際のオブジェクトは、最終的に参照したいオブジェクトです。


以下では、単純なプロキシ パターンの基本的な実装を説明するために、

メッセージの送信を例として取り上げます:

まず目的を明確にします: メッセージがあり、このメッセージを送信する必要があり、対応するインターフェース MessageHandler はこの目的に従って定義されます。追加の操作が必要です。メッセージの長さが指定された長さを超えてはならず、空であってはいけないことを確認する必要があるとします。また、指定された回数を超えた場合、関連する情報が送信された回数をカウントする必要があるとします。アラートを出力します。この追加操作はプロキシ パターンを通じて実装します。以下は対応するクラス図とサンプルコードです。



//接口定义  
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

この例では、メッセージ送信プロセス中にさまざまな必要な追加の処理メソッドを簡単に追加できます。また、電子メールによるメッセージ送信を SMS 送信に置き換えるなど、メッセージ処理メソッドを簡単に置き換えることもできます。発信者に気付かれずにメッセージを送信できます。プロキシは、特定のオブジェクトから追加の操作を分離したい場合に非常に役立ちます。特に、簡単に変更できるようにしたい場合や、特定のオブジェクトのメソッドが実行される前に追加の操作を挿入したい場合に便利です。


動的プロキシ

Java での動的プロキシ メカニズムの導入により、プロキシ モデルの考え方がより完全かつ進歩的になり、プロキシの動的作成が可能になり、プロキシされたメソッドへの動的呼び出しがサポートされます。 Java 動的プロキシ クラスは Java.

lang.reflect パッケージの下にあり、通常、次の 2 つのクラスが含まれます:

(1)。インターフェイス InvocationHandler: このインターフェイスでは 1 つのメソッドのみが定義されています

Object: invoke(Object obj 、メソッドメソッド、Object[] 引数)。実際の使用では、通常、最初のパラメータ obj はプロキシ クラスを指し、method は上記の例の request() などのプロキシ メソッド、args はメソッドのパラメータ配列です。この抽象メソッドはプロキシ クラスに動的に実装されます。

(2).Proxy: このクラスは動的プロキシ クラスであり、その機能は上記の例の ProxySubject に似ており、主に次の内容が含まれます:

Protected Proxy(InvocationHandler h):
Constructor、推定内部 h 割り当てに使用されます。 静的クラス getProxyClass (ClassLoader ローダー、Class[] インターフェイス): プロキシ クラスを取得します。ここで、ローダーはクラス ローダー、インターフェイスは実際のクラスが所有するすべてのインターフェイスの配列です。

Static Object newProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh): プロキシ クラスのインスタンスを返します。返されたプロキシ クラスはプロキシ クラスとして使用できます (プロキシ クラスは Subject インターフェイス メソッドで宣言できます)。 )。


いわゆるダイナミック プロキシはクラスです。これは実行時に生成されるクラスであり、生成するときにそれに一連のインターフェイスを提供する必要があり、クラスはこれらのインターフェイスを実装することを宣言します。もちろん、このクラスのインスタンスをこれらのインターフェイスのいずれかとして使用できます。もちろん、この動的プロキシは実際にはプロキシです。インスタンスを生成するときは、実際の作業を引き継ぐハンドラーを提供する必要があります。 動的プロキシを介して情報を送信する上記の例を再実装してみましょう。


上記の例に基づいて、最初に SMS 経由でメッセージを送信するための処理クラスを追加します。



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()方法中传递进来了代理对象,当你需要区分请求来源时这是非常有用的,例如你可以通过判断传入的方法名屏蔽掉某些方法的执行!动态代理机制并不是会很频繁使用的方法,它通常用来解决一些特定情况下的问题,因此不要盲目的为了使用而使用,要根据自己的实际需求来决定!

以上がJava プロキシ モードの詳細な分析 (画像とテキスト)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。