Proxy of Java Design Pattern

Source: Internet
Author: User

Proxy of Java Design Pattern

Java Design PatternStatic proxy and dynamic proxy
The proxy mode is the structure mode of the object. The proxy mode provides a proxy object for an object and controls the reference to the original object by the proxy object. An individual or institution acts on behalf of another entity or institution. In some cases, a client does not want or cannot directly reference an object, and the proxy object can play a mediation role between the client and the target object.

Static proxy

Scenario:
For example, if you want to buy a plane ticket, your behavior is to buy a plane ticket. You can buy a ticket through a third-party agent platform, such as Alibaba, where to go, Ctrip, and other platforms to help you buy it, this platform acts as an agent, so you don't have to buy a ticket directly at the airline. You only need to inform the proxy role of your behavior requirements.

Code
1. Create a behavior Interface

Public interface BuyTicketInterface {// void butTicket ();}

2. Create a client. I want to buy a ticket to implement the behavior defined in the interface. Then execute your own behavior.

Public class TravelPeople implements BuyTicketInterface {// the behavior and requirements of the client are as follows. Public void butTicket () {System. out. println ("Buy a May 1 flight from Chongqing Jiangbei airport to Beijing Capital Airport, between and ");}}

3. When creating the proxy function, the proxy must also implement the behavior of buying tickets. Otherwise, the proxy will execute the ticket for the client to complete the requirements of the client. The Code is as follows.

Public class BuyTicketProxy implements BuyTicketInterface {private TravelPeople travelPeople; // public BuyTicketProxy () {this. travelPeople = new TravelPeople ();}/*** calls the proxy action during execution, and the proxy acts for the client. */Public void buyTicket () {if (travelPeople! = Null) {travelPeople. buyTicket ();}}}

4. Use an agent to buy tickets. Terminal behavior and agent processing to achieve the function of purchasing tablets;
The Code is as follows:

Public class TicketService {public static void main (String [] args) {TicketService. startBuyTicket ();} // start to buy a ticket. It seems that the transaction is done by the agent and the ticket center. In fact, the transaction is performed by the client. Public static void startBuyTicket () {BuyTicketInterface buyTick = new BuyTicketProxy (); buyTick. buyTicket ();}}

Running result

Buy a May 1 flight from Chongqing Jiangbei airport to Beijing Capital Airport between and

Advantages and disadvantages of static proxy Mode:
Advantage: the business class only needs to focus on the business logic itself, ensuring the reusability of the business class. This is a common advantage of proxy and reduces the coupling of business logic.
Disadvantages:
1) An interface of a proxy object serves only one type of object. If there are many proxy methods, proxy is required for each method, static proxies cannot be competent when the program size is relatively large.
2) if a method is added to the interface, all the proxy classes also need to implement this method except all the implementation classes. Added the complexity of code maintenance.

The problem arises. If you want to use the proxy mode in the preceding method (static proxy), the real role must implement the existing one and use it as the internal attribute of the proxy object. However, in actual use, a real role must correspond to a proxy role, but a large amount of use will lead to a sharp expansion of the class. In addition, if you do not know the real role in advance, how should we use the proxy? This problem can be solved through the dynamic proxy class of Java.

Dynamic proxy

The source code of the dynamic proxy class is dynamically generated by JVM according to reflection and other mechanisms during the program running, so there is no bytecode file of the proxy class. The relationship between the proxy class and the delegate class is determined when the program is running. Implemented through the Java reflection mechanism.

1. first look at the Java API closely related to the dynamic proxy.

1) java. lang. reflect. Proxy

This is the parent class of all dynamic proxy classes generated by the Java Dynamic proxy mechanism. It provides a set of static methods to dynamically generate proxy classes and their objects for a group of interfaces.
The proxy code list is as follows:

// Method 1: This method is used to obtain the call processor static InvocationHandler getInvocationHandler (Object proxy) associated with the specified proxy Object. // Method 2: this method is used to obtain the static Class getProxyClass (ClassLoader loader, Class [] interfaces) Class Object associated with the specified Class loader and a group of interfaces. // method 3: this method is used to determine whether the specified Class object is a dynamic proxy Class static boolean isProxyClass (Class cl) // Method 4: this method is used to generate a static Object newProxyInstance (ClassLoader loader, Class [] interfaces, InvocationHandler h) for the specified Class loader, a group of interfaces, and call the processor)

2) java. lang. reflect. InvocationHandler

This is to call the processor interface. It customizes an invoke Method for centralized processing of method calls on a dynamic proxy object. Generally, this method implements proxy access to the delegate class. Each time a dynamic proxy class object is generated, a corresponding call processor object must be specified.

The InvocationHandlerd code list is as follows:

// This method is used to centrally process all method calls in the dynamic proxy class. The first parameter is a proxy instance, and the second parameter is the called method object // The third method is the call parameter. The call processor performs preprocessing based on these three parameters or distributes the request to the delegate class instance for reflection and execution of Object invoke (Object proxy, Method method, Object [] args)

3) java. lang. ClassLoader

This is a class loader class that loads the class bytecode into the Java Virtual Machine (JVM) and defines class objects for it before the class can be used. The dynamic Proxy class generated by the Proxy static method also needs to be loaded by the class loader for use, the only difference between it and common classes is that its bytecode is dynamically generated by the JVM at runtime, rather than pre-stored in any one. class file.
Each time a dynamic proxy class object is generated, a Class Loader object must be specified.

2. Dynamic proxy implementation steps
The procedure is as follows:
A. Implement the InvocationHandler interface to create your own call Processor
B. Provide ClassLoader and Proxy Interface Types for Proxy classes to create dynamic Proxy classes.
C. Use the reflection mechanism to obtain the constructor of the dynamic proxy class by calling the processor type as the parameter
D. Use the constructor of the dynamic proxy class to create a dynamic proxy class object with the called processor object as the parameter

// InvocationHandlerImpl implements the InvocationHandler interface and can distribute and forward method calls from the proxy class to the delegate class. // It usually contains references pointing to the delegate class instance, call InvocationHandler handler = new InvocationHandlerImpl (...) to really execute the method forwarded by the dispatch (..); // use Proxy to dynamically create the Class Object Class clazz = Proxy for a group of interfaces including Interface interfaces. getProxyClass (classLoader, new Class [] {Interface. class ,...}); // obtain the Constructor constructor = clazz from the generated class object through reflection. getConstructor (new Class [] {InvocationHandler. class}); // create a dynamic Proxy instance through the constructor object Interface Proxy = (Interface. newInstance (new Object [] {handler });

3. Dynamic proxy implementation example

Create interface;

public interface BuyTicketInterface {    void buyTicket();}

Create the call handler class corresponding to the dynamic proxy class

Public class BuyTicketHandler implements InvocationHandler {/*** call handler class corresponding to the dynamic proxy class */private Object orginObject; // The proxy class holds an Object of the delegate class to reference public BuyTicketHandler (Object orginObject) {this. orginObject = orginObject;} public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {Object result; // before calling a Method; doBefore (); // use the reflection mechanism to distribute requests to the delegate class for processing. Method invoke returns the Object as the Method execution result. // Because the sample program does not return values, the result = method is ignored here. invoke (this. orginObject, args); doAfter (); return result;} private void doBefore () {System. out. println ("start buying tickets");} private void doAfter () {System. out. println ("ticket call ");}}

The factory that generates dynamic proxy objects. The factory method lists how to generate dynamic proxy objects.

/*** Generate the factory of the dynamic proxy object. */public class DynProxyFactory {// The customer class calls this factory method to obtain the proxy object. // For the customer class, it does not know whether the returned result is a proxy object or a delegate object. Public static Subject getInstance () {Subject delegate = new RealSubject (); InvocationHandler handler = new SubjectInvocationHandler (delegate); Subject proxy = null; proxy = (Subject) Proxy. newProxyInstance (delegate. getClass (). getClassLoader (), delegate. getClass (). getInterfaces (), handler); return proxy ;}}

Dynamic proxy customer

Public class BuyTicketProxy {// The customer class calls this factory method to obtain the proxy object. // For the customer class, it does not know whether the returned result is a proxy object or a delegate object. Public static BuyTicketInterface startBuy () {// create the object BuyTicketInterface buyTicket = new TravelPeople (); // create a dynamic proxy InvocationHandler handler = new BuyTicketHandler (buyTicket ); // obtain the object through reflection. BuyTicketInterface buy = (BuyTicketInterface) Proxy. newProxyInstance (buyTicket. getClass (). getClassLoader (), buyTicket. getClass (). getInterfaces (), handler); return buy ;}}

Create a test;

BuyTicketInterface buy = BuyTicketProxy.startBuy();        buy.buyTicket();

Running result:

Start to buy a ticket to buy a flight from Chongqing Jiangbei airport to Beijing Capital Airport on June 23, May 1. The ticket will be called between and.

Summary: first, some characteristics of the dynamically generated proxy class itself. 1) package: If the proxy interface is public, it will be defined in the top-level package (that is, the package path is empty ), if the proxy interface has a non-public interface (because the interface cannot be defined as protect or private, it is the default package access level except public ), it will be defined in the package where the interface is located (assuming that the com. ibm. A non-public interface A in the developerworks package, the newly generated proxy class is in the com. ibm. developerworks), the purpose of this design is to maximize the guarantee that dynamic proxy classes will not be successfully defined and accessed due to packet management issues; 2) Class modifier: the proxy class has the final and public modifiers, which means it can be accessed by all classes but cannot be inherited again. 3) Class Name: The format is "$ ProxyN ", N is an incremental Arabic number, representing the dynamic Proxy class generated for the nth time of the Proxy class. It is worth noting that Not every time you call the Proxy's static method to create a dynamic Proxy class, the N value is increased because if you attempt to create a dynamic Proxy class repeatedly for the same group of interfaces (including interfaces in the same order, it intelligently returns the Class Object of the previously created proxy class, instead of creating a new proxy class, which saves unnecessary code generation, this improves the efficiency of creating proxy classes.

Advantages:
The biggest advantage of dynamic proxy compared with static proxy is that all methods declared in the interface are transferred to the InvocationHandler. invoke method that calls the processor ). In this way, when there are a large number of interface methods, we can flexibly process them without the need to transfer each method like a static proxy. In this example, the invoke method is embedded with a specific peripheral business (record the time before and after processing the task and calculate the time difference ).

Disadvantages:
Proxy has been designed perfectly, but there are still limitations, that is, it cannot get rid of the shackles of interface Proxy, because its design is doomed to this regret. Think back to the inheritance relationships of the dynamically generated Proxy classes. They are already destined to have a common parent class called Proxy. The Inheritance Mechanism of Java is doomed to the failure of these dynamic proxy classes to implement the dynamic proxy for the class, because multi-inheritance is essentially not feasible in Java.

There are many reasons that people can deny the necessity for class proxy, but there are also some reasons, I believe it will be better to support class dynamic proxy. The division of interfaces and classes is not very obvious, but it has become so refined in Java. If you only consider the declaration of a method and whether it is defined, there is a mixture of the two. Its name is abstract class. The realization of dynamic proxy for abstract classes also has its inherent value. In addition, there are some historical classes that will never be associated with dynamic proxies because no interfaces are implemented. All these are a small pity.
Finally, the agent design mode depends on the project's own situation, so as to maximize the design function of the design mode. It makes projects easy to expand and has low coupling. Is the way forward.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.