Home > Java > javaTutorial > body text

Detailed analysis of Java proxy mode (picture and text)

黄舟
Release: 2017-03-22 10:19:54
Original
1217 people have browsed it

This article mainly introduces the relevant information of Javaproxy mode in detail, which has certain reference value. Interested friends can refer to it

The proxy mode is ours One of the more commonly used design patterns. The new idea is to insert a proxy object between the actual object and the caller in order to provide additional processing or different operations. These additional operations usually require communication with the actual object. The roles generally involved in the proxy pattern are:

Abstract role: declare the common interface of the real object and the proxy object;

Proxy role: The proxy object role contains a reference to the real object internally, so that the real object can be manipulated. At the same time, the proxy object provides the same interface as the real object so that it can replace the real object at any time. At the same time, the proxy object can add other operations when performing operations on the real object, which is equivalent to encapsulating the real object.

Real role: The real object represented by the proxy role is the object we ultimately want to reference.

The following takes Sending a message as an example to illustrate the basic implementation of a simple proxy mode:

First clarify the purpose: there is a message that needs To send this message, define the corresponding interface MessageHandler according to this purpose. Additional operations required: Suppose we need to verify that the length of the message cannot exceed the specified length and cannot be empty, and we need to count the number of times relevant information is sent. If the number exceeds the specified number, we need to output an alert. We implement this additional operation through the proxy pattern. The following is the corresponding class diagram and sample code.


##

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

In the example, we can easily add various required additional processing methods during the message sending process, and also It can conveniently replace the message processing method, such as replacing sending a message via Email with sending a message via SMS, and the caller will not be aware of it at all! Proxies are very useful any time you want to separate some additional operations from the specific object, especially if you want to be able to make changes easily, or if you want to insert some additional operations before the method of the specific object is executed!


Dynamic Agent

The introduction of the dynamic agent mechanism in Java has made the idea of ​​the agent model more complete and progressive. It allows dynamic creation of agents and Supports dynamic invocation of proxied methods. The Java dynamic proxy class is located under the Java.

lang.reflect package, which generally involves the following two classes:

(1). Interface InvocationHandler: This interface only defines A method

Object: invoke(Object obj,Method method, Object[] args). In actual use, the first parameter obj generally refers to the proxy class, method is the proxy method, such as request() in the above example, and args is the parameter array of the method. This abstract method is implemented dynamically in the proxy class.

(2).Proxy: This class is a dynamic proxy class, its function is similar to the ProxySubject in the above example, which mainly includes the following contents:

Protected Proxy(InvocationHandler h):
Constructor is estimated to be used to assign a value to the internal h. Static Class getProxyClass (ClassLoader loader, Class[] interfaces): Get a proxy class, where loader is the class loader and interfaces is an array of all interfaces owned by the real class.

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h): Returns an instance of the proxy class. The returned proxy class can be used as the proxy class (the proxy class can be used method declared in the Subject interface).


The so-called Dynamic Proxy is a class: it is a class generated at runtime. When generating it, you must provide a set of interfaces to it, and then the class declares that it implements these interfaces. . You can of course use instances of this class as any of these interfaces. Of course, this Dynamic Proxy is actually a Proxy. It will not do substantive work for you. When generating its instance, you must provide a handler, which will take over the actual work. Let's re-implement the above example of sending information through a dynamic proxy!


Based on the above example, we first add a processing class for sending messages through 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 !
Copy after login

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

The above is the detailed content of Detailed analysis of Java proxy mode (picture and text). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template