[Go] In-depth understanding of Java proxy Mechanism

Source: Internet
Author: User

The article is transferred from the network, the original text can not be tested, give the Reprint article link: http://blog.csdn.net/rokii/article/details/4046098

See the project code to see a piece of very beautiful agent mechanism, tidy up:

Dynamic proxy is actually the Java.lang.reflect.Proxy class dynamically generates a class byte based on all of the interfaces you specify, which inherits the proxy class and implements all of the interfaces you specify (An array of interfaces that you passed in the parameter), and then the class byte is loaded into the system using the ClassLoader you specified, and finally the object of such a class is generated, and some properties of the object, such as Invocationhandler, are initialized. and all the interfaces corresponding to the method member. Returns the object to the calling client after initialization. So the client gets a proxy object that implements all of your interfaces. Take a look at example analysis:

Business interface

 Public Interface  publicvoid  processbusiness ();}

Business interface Implementation Class

 Public class Implements businessprocessor {  publicvoid  processbusiness () {System.out.println ("Processi   Ng business ... "); }}

Business proxy class

ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method; Public classBusinessprocessorhandlerImplementsInvocationhandler {PrivateObject target =NULL; Businessprocessorhandler (Object target) { This. target =Target; } Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Can do something here before process your business"); Object result=Method.invoke (target, args); System.out.println ("You can does something here after process your business"); returnresult; }}

Client Application Class

ImportJava.lang.reflect.Field;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Modifier;ImportJava.lang.reflect.Proxy; Public classTest { Public Static voidMain (string[] args) {
Businessprocessorimpl Bpimpl=NewBusinessprocessorimpl ();
Businessprocessorhandler Handler=NewBusinessprocessorhandler (Bpimpl);
Businessprocessor BP=(businessprocessor) proxy.newproxyinstance (Bpimpl.getclass (). getClassLoader (), Bpimpl.getclass ().  Getinterfaces (), handler); Bp.processbusiness (); }}

Printing results:

You can do something this before process your business
Processing business .....
You can does something here after process your business

Through the results we can easily see the role of proxy, it can be in your core business methods before and after doing some of the auxiliary work you want to do, such as log logs, security mechanisms and so on.

Now let's examine how the above class works.

Class one or two nothing to say.

Let's take a look at class three: Implement the Invoke method of the Invocationhandler interface. in fact, this class is the final proxy call fixed interface method . Proxy Regardless of how the client's business method is implemented. When the client calls proxy, it only

The Invoke interface of Invocationhandler is called , so our real implementation method must be called in the Invoke method. The relationship is as follows:

Businessprocessorimpl Bpimpl = new Businessprocessorimpl ();
Businessprocessorhandler handler = new Businessprocessorhandler (BPIMPL);

Businessprocessor BP = (businessprocessor) proxy.newproxyinstance (...);

Bp.processbusiness ()-->invocationhandler.invoke ()-->bpimpl.processbusiness ();

So what exactly is BP about? Let's change the main method and look at it:

 Public Static void Main (string[] args) {  new  Businessprocessorimpl ();   New Businessprocessorhandler (Bpimpl);   = (businessprocessor) proxy.newproxyinstance (Bpimpl.getclass (). getClassLoader (), Bpimpl.getclass (). Getinterfaces (), handler);  Bp.processbusiness ();  System.out.println (Bp.getclass (). GetName ()); }

Output Result:

You can do something this before process your business
Processing business .....
You can does something here after process your business
$Proxy 0

BP turned out to be an object of the $proxy0 class. So what does this class look like? Good. Let's write another two ways to print out this class and see what the three heads is. We write the following two static methods below main.

 Public StaticString Getmodifier (intmodifier) {String result= ""; Switch(modifier) { CaseModifier.PRIVATE:result= "Private";  CaseModifier.PUBLIC:result= "Public";  CaseModifier.PROTECTED:result= "protected";  CaseModifier.ABSTRACT:result= "Abstract";  CaseModifier.FINAL:result= "Final";  CaseModifier.NATIVE:result= "Native";  CaseModifier.STATIC:result= "Static";  CaseModifier.SYNCHRONIZED:result= "Synchronized";  CaseModifier.STRICT:result= "Strict";  CaseModifier.TRANSIENT:result= "transient";  CaseModifier.VOLATILE:result= "volatile";  CaseModifier.INTERFACE:result= "Interface"; }  returnresult;}  Public Static voidprintclassdefinition (Class clz) {String clzmodifier=Getmodifier (Clz.getmodifiers ()); if(clzmodifier!=NULL&&!clzmodifier.equals ("") ) {Clzmodifier= Clzmodifier + ""; } String Superclz=Clz.getsuperclass (). GetName (); if(superclz!=NULL&&!superclz.equals ("") ) {Superclz= "Extends" +Superclz; } class[] Interfaces=clz.getinterfaces (); String inters= "";  for(inti=0; i<interfaces.length; i++){   if(i==0) {inters+ = "Implements"; } inters+=Interfaces[i].getname (); } System.out.println (Clzmodifier+clz.getname () + "" + Superclz + "+inters); System.out.println ("{"); Field[] Fields=Clz.getdeclaredfields ();  for(inti=0; i<fields.length; i++) {String modifier=Getmodifier (Fields[i].getmodifiers ()); if(modifier!=NULL&&!modifier.equals ("") ) {modifier= modifier + ""; } String fieldName=Fields[i].getname (); String FieldType=Fields[i].gettype (). GetName (); System.out.println ("+modifier + FieldType +" "+ FieldName +"; ");    } System.out.println (); Method[] Methods=Clz.getdeclaredmethods ();  for(inti=0; i<methods.length; i++) {Method method=Methods[i]; String modifier=Getmodifier (Method.getmodifiers ()); if(modifier!=NULL&&!modifier.equals ("") ) {modifier= modifier + ""; } String methodName=Method.getname (); Class Returnclz=Method.getreturntype (); String Retruntype=Returnclz.getname (); Class[] Clzs=method.getparametertypes (); String paralist= "(";  for(intj=0; j<clzs.length; J + +) {paralist+=Clzs[j].getname (); if(J! = Clzs.length-1) {paralist+= ", "; }} paralist+= ")"; Clzs=method.getexceptiontypes (); String Exceptions= "";  for(intj=0; j<clzs.length; J + +){    if(j==0) {Exceptions+ = "throws"; } Exceptions+=Clzs[j].getname (); if(J! = Clzs.length-1) {Exceptions+= ", "; }} Exceptions+= ";"; String Methodprototype= Modifier +retruntype+ "" +methodname+paralist+exceptions; System.out.println ("    "+Methodprototype); } System.out.println ("}"); }
View Code

Rewrite the Main method again

 Public Static void Main (string[] args) {  new  Businessprocessorimpl ();   New Businessprocessorhandler (Bpimpl);   = (businessprocessor) proxy.newproxyinstance (Bpimpl.getclass (). getClassLoader (), Bpimpl.getclass (). Getinterfaces (), handler);  Bp.processbusiness ();  System.out.println (Bp.getclass (). GetName ());   = Bp.getclass ();  Printclassdefinition (CLZ); }

Now let's look at the output:

You can do something this before process your business
processing business .....
You can does something here after process your business
$Proxy 0
$Proxy 0 extends Java.lang.reflect.Proxy implement S com.tom.proxy.dynamic.BusinessProcessor
{
    java.lang.reflect.Method M4;
    java.lang.reflect.Method m2;
    Java.lang.reflect.Method M0;
    Java.lang.reflect.Method m3;
    Java.lang.reflect.Method M1;

    void processbusiness ();
    int hashcode ();
    Boolean equals (Java.lang.Object);
    java.lang.String toString ();
}

Obviously, the Proxy.newproxyinstance method will do several things as follows:

1, according to the second parameter passed interfaces dynamically generate a class to implement the interface in interfaces, in this case the Processbusiness method of the Businessprocessor interface. and inherit the proxy class, rewrite the Hashcode,tostring,equals and other three methods. Concrete implementation can be see Proxygenerator.generateproxyclass (...); In this example, the $proxy0 class is generated

2, the newly generated class is loaded into the JVM by the first parameter passed in Classloder. Upcoming $PROXY0 class Load

3, using the third parameter, call $proxy0 's $proxy0 (Invocationhandler) constructor to create the $proxy0 object, and use the interfaces parameter to traverse all of its interfaces. and generates several method member variables for the method object initialization object

4, the instance of $proxy0 is returned to the client.

It's good now. Let's see how the client is tuned.

1, the client gets the instance object of $proxy0, because $proxy0 inherits the Businessprocessor, so the conversion to businessprocessor no problem.

Businessprocessor BP = (businessprocessor) proxy.newproxyinstance (...);

2,bp.processbusiness ();

$proxy0.processbusiness () is actually called, so the implementation of $proxy0.processbusiness () is to invoke the Invoke method through Invocationhandler!

[Go] In-depth understanding of Java proxy Mechanism

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.