Java design mode 9: Proxy mode

Source: Internet
Author: User
Tags throwable

Proxy mode

The definition of proxy mode is simple: Provide a proxy object to an object, and the proxy object controls the reference to the original object .

Structure of the proxy mode

In some cases, a customer does not want to live without being able to refer directly to an object, which can mediate between the client and the target object through the proxy object. The roles in proxy mode are:

1. Abstract Object Role

A common interface between the target object and the proxy object is declared so that the proxy object can be used wherever the target object can be used

2. Target object role

Defines the target object that the proxy object represents

3. Agent Object Role

The proxy object contains a reference to the target object, so that the target object can be manipulated at any time, and the proxy object provides the same interface as the target object so that the target object can be substituted at any time

Static Proxy Example

If there is a method inside an interface that wants to add something to the interface before and after it is called, you can use proxy mode. Static Proxy is the simplest implementation of proxy mode, first define a static proxy interface, there is a print () method, look at:

 Public Interface statichelloworld{    //  define an interface with a print method    void print ();}

Let a subclass implement it and print a word "Hello world" out:

 Public class Implements statichelloworld{    publicvoid  print ()    {        System.out.println (" Hello World ");}    }

Create a proxy object for this interface to implement the proxy for the docking port implementation class. Note that the focus here is that the proxy object and the actual object implement the same interface , because you want the proxy object to replace the actual object at any time:

 public  class  staticproxy implements   statichelloworld{ private          Statichelloworld Statichelloworld;  public   Staticproxy (Statichelloworld Statichelloworldimpl) { this . Statichelloworld = Statichelloworldimpl;  public  void   print () {System.out.println ( "before Hello world!"        );        Statichelloworld.print (); System.out.println ( after Hello world!    ); }}

Write a class to invoke the proxy object and pass in an actual object in the constructor of the proxy object:

 Public class statictestmain{    publicstaticvoid  main (string[] args)    {         New  Statichelloworldimpl ();         New Staticproxy (SHW);        Sp.print ();    }}

The result of the operation is:

Before Hello world! Hello worldafter helloworld!

This is obvious, not to mention.

Disadvantages of static proxies

The static proxy is characterized by the proxy class of the static proxy, which is created by the programmer, and the static agent's. class file already exists before the program runs .

From a static proxy, you can see that the static proxy pattern does have a proxy object that controls the reference to the actual object and uses the actual object through the proxy object. This mode can also be used when the agent is small, but a large amount of agent, there are three relatively large shortcomings:

1, if you want to change a proxy content, such as I do not want to enter "Hello world" before and after "before XXX" and "after xxx", want to output before and after the system current time, you must write a new proxy object. This can easily cause the expansion of proxy objects.

2, the agent content can not be reused, that is, "before xxx" and "after XXX" can only be used for a certain class, another class if you want to use this proxy content, you must also write one, the same, the result is the infinite expansion of the proxy class

3, the interface if a new method, the actual object implementation of this method, the proxy object must also add content, to the new method to add agent content (if necessary)

Example of implementing dynamic Proxy using proxy class proxies in JDK

Because of the limitation of static agent, the concept of dynamic agent is produced. Take a look at the first or define a dynamic proxy interface:

 Public Interface dynamichelloworld{    //  Dynamic proxy class, there is a print () method     String print ();}

Write a class to implement it, print the method print "Enter dynamichelloworldimpl.print ()" and Return "Dynamichelloworldimpl":

 Public class Implements dynamichelloworld{    public  String print ()    {        System.out.println ("Enter Dynamichelloworldimpl.print () ");                 return "Dynamichelloworldimpl";    }}

The most critical part of the dynamic proxy class is also a less well understood part. In Java, dynamic proxies need to implement the Invocationhandler interface.

Invocationhandler interface There is only one method invoke (), as to how to achieve, completely look at the user's own preferences, not fixed. You can put newinstance, the process of generating a dynamic proxy class, into the Invocationhandler implementation class as follows:

 Public classDynamicproxyImplementsinvocationhandler{PrivateObject Target;  Publicobject Newinstance (object target) { This. target =Target; returnproxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinterfaces (), This); }         Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Before Dynamicproxy");        Method.invoke (target, args); System.out.println ("After Dynamicproxy"); return NULL; }}

You can also have the dynamic proxy class generated outside, just passing in a target in the constructor:

 Public classDynamicproxyImplementsinvocationhandler{PrivateObject Target;  PublicDynamicproxy (Object target) { This. target =Target; }         Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Before Dynamicproxy");        Method.invoke (target, args); System.out.println ("After Dynamicproxy"); return NULL; }}

If the former is written, then the main function is to write this:

 Public class dynamictestmain{    publicstaticvoidthrows  Exception    {         New dynamicproxy ();         New Dynamichelloworldimpl ();         = (Dynamichelloworld) dp.newinstance (DHWI);        Dhw.print ();    }}

If this is the latter way of writing, then the main function is to write:

 Public classdynamictestmain{ Public Static voidMain (string[] args)throwsException {dynamichelloworld dhwi=NewDynamichelloworldimpl (); Invocationhandler IH=NewDynamicproxy (DHWI); Dynamichelloworld DHW=(Dynamichelloworld) Proxy. Newproxyinstance (Dynamichelloworld.class. getClassLoader (),NewClass<?>[]{dynamichelloworld.class}, IH);    Dhw.print (); }}

Either way, the result is the same:

Before Dynamicproxyenter Dynamichelloworldimpl.print () after Dynamicproxy

Dynamic Agent Parsing

The above two formulations are essentially the same. Original aim, summed up, to achieve a dynamic agent can be summarized as the following four steps:

1. Gets the object to be proxied, that is, the actual object

2, implement the Invocationhandler interface, generate the actual agent content

3, using the Proxy.newinstance () method to generate a proxy content, the third parameter passed into the Invocationhandler implementation class

4, the proxy object calls the internal method of the interface

Dynamic proxy, using the dynamic compilation + reflection technique, transforms the method call of the actual object into the call of the Invoke method of implementing class of the incoming Invocationhandler interface , which is the key point of the dynamic proxy pattern implementation. To prove this is not difficult, in the program to hit the breakpoint with the code:

Press F5 to perform the next step and see the program go to the Invoke method of the Invocationhandler implementation class:


Execute Methd.invoke (target, args) and see the console print out the phrase "Enter dynamichelloworldimpl.print ()", Describes the print () method that executes the actual object Dynamichelloworldimpl:

This proves our conclusion that the call to the actual object method is translated into a call to the Invoke method of the Invocationhandler implementation class

Advantages of dynamic agents

1, the most intuitive, the class is a lot less

2, the agent content is Invocationhandler interface implementation class can be reused, can be used for a interface, can also be used for the B interface, a interface with the Invocationhandler interface to implement Class A agent, do not want to use, can be easily replaced by the Invocationhandler interface to implement the agent B

3, the most important, with the dynamic agent, you can not modify the original code on the basis of the original code on the basis of doing the operation, which is AOP is the aspect of programming

Java design mode 9: Proxy mode

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.