Java Dynamic Proxy)

Source: Internet
Author: User

Dynamic proxy can provide access to another object, while hiding the fact of the actual object, the proxy object hides the actual object from the customer. The dynamic proxy can process other requests. When direct access to some classes is not allowed,

Or you need to perform some special processing on the access. In this case, you can consider using a proxy. Currently, the Java Development Kit provides support for dynamic proxies, but currently only supports the implementation of interfaces.
 
Mainly through the java. lang. reflect. Proxy class and java. lang. reflect. InvocationHandler interface. The Proxy class is mainly used to obtain dynamic Proxy objects, and the InvocationHandler interface is used to constrain caller behavior.

"Write an ArrayList proxy, which internally implements the same functions as the ArrayList and can calculate the running time of each method ." There is no answer to this question. Let's look at the implementation:


Package example;

Import java. lang. reflect. InvocationHandler;
Import java. lang. reflect. Method;
Import java. lang. reflect. Proxy;
Import java. util. ArrayList;
Import java. util. List;
Import java. util. concurrent. TimeUnit;
/**
*-----------------------------------------
* @ Description TODO
* @ Author fancy
* @ Mailbox fancydeepin@yeah.net
* @ Date 2012-8-27 <p>
*-----------------------------------------
*/Www.2cto.com
Public class ProxyApp {


Public static void main (String [] args ){

// ArrayList proxy, used to calculate the time required for each method call
List <Integer> arrayListProxy = (List <Integer>) Proxy. newProxyInstance (
ArrayList. class. getClassLoader (),/* defines the class loader of the proxy class. It is used to create a proxy object. It may not necessarily be an ArrayList or another class loader */
ArrayList. class. getInterfaces (),/* List of interfaces implemented by the proxy class */
New InvocationHandler () {/* specifies the call handler for a method call. An anonymous internal class is used here */

Private ArrayList <Integer> target = new ArrayList <Integer> (); // target object (truly operated object)
/**
* <B> method Description: </B>
* <P style = "margin-left: 20px; color: # A52A2A;">
* Process method calls on the proxy instance and return results
* @ Param proxy object (note that it is not the target object)
* @ Param method: the proxy method.
* @ Param args parameter set of the proxy method
* @ Return <span style = "color: #008080;"> return method call results </span>
*/
@ Override
Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {

Long beginTime = System. currentTimeMillis (); // start time
TimeUnit. MICROSECONDS. sleep (1 );
Object obj = method. invoke (target, args); // actually called method, and accept the return value of the method
Long endTime = System. currentTimeMillis (); // End Time
System. out. println ("[" + method. getName () + "] spend" + (endTime-beginTime) + "ms ");
Return obj; // return the return value of the actually called Method

}

}
);
ArrayListProxy. add (2 );
ArrayListProxy. add (4 );
System. out. println ("--------- iteration ---------");
For (int I: arrayListProxy ){
System. out. print (I + "\ t ");
}
}
}

Output result in the background:


[Add] spend 2 MS
[Add] spend 1 MS
--------- Iteration ---------
[Iterator] spend 1 MS
2 4

From the code point of view, the anonymous internal class is used. In this way, the InvocationHandler can only be used once. If the same InvocationHandler is used in multiple places, it can be abstracted into a separate class:


Package test;

Import java. lang. reflect. InvocationHandler;
Import java. lang. reflect. Method;
Import java. util. concurrent. TimeUnit;

Public class MyInvocationHandler implements InvocationHandler {

Private Object target; // target Object

Public MyInvocationHandler (Object target ){

This.tar get = target;
}

@ Override
Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {

Long beginTime = System. currentTimeMillis ();
TimeUnit. MICROSECONDS. sleep (1 );
Object obj = method. invoke (target, args );
Long endTime = System. currentTimeMillis ();
System. out. println ("[" + method. getName () + "] spend" + (endTime-beginTime) + "ms ");
Return obj;

}

}


Change the client call:


Package example;

Import java. lang. reflect. Proxy;
Import java. util. ArrayList;
Import java. util. List;
/**
*-----------------------------------------
* @ Description TODO
* @ Author fancy
* @ Mailbox fancydeepin@yeah.net
* @ Date 2012-8-27 <p>
*-----------------------------------------
*/
Public class ProxyApp {


Public static void main (String [] args ){

// ArrayList proxy, used to calculate the time required for each method call
List <Integer> arrayListProxy = (List <Integer>) Proxy. newProxyInstance (
ArrayList. class. getClassLoader (),/* defines the class loader of the proxy class. It is used to create a proxy object. It may not necessarily be an ArrayList or another class loader */
ArrayList. class. getInterfaces (),/* List of interfaces implemented by the proxy class */
New MyInvocationHandler (new ArrayList <Integer> ()/* specifies the call handler for a method call. An anonymous internal class is used here */
);
ArrayListProxy. add (2 );
ArrayListProxy. add (4 );
System. out. println ("--------- iteration ---------");
For (int I: arrayListProxy ){
System. out. print (I + "\ t ");
}
}
}

From the code above, the client knows the actual target object of the proxy and how to create such a proxy object. If you want to hide all the information on the client, you can move the code to a class and encapsulate it:


Package example;

Import java. lang. reflect. InvocationHandler;
Import java. lang. reflect. Method;
Import java. lang. reflect. Proxy;
Import java. util. ArrayList;
Import java. util. List;
Import java. util. concurrent. TimeUnit;

/**
*-----------------------------------------
* @ Description TODO
* @ Author fancy
* @ Mailbox fancydeepin@yeah.net
* @ Date 2012-8-27 <p>
*-----------------------------------------
*/
Public class ProxyUtil {

Public enum ArrayListProxy {
PROXY;

Private Object target;

ArrayListProxy (){
This.tar get = new ArrayList <Object> ();
}

Public List getInstance (){

Return (List) Proxy. newProxyInstance (ArrayList. class. getClassLoader (), ArrayList. class. getInterfaces (),
New InvocationHandler (){

@ Override
Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {

Long beginTime = System. currentTimeMillis ();
TimeUnit. MICROSECONDS. sleep (1 );
Object obj = method. invoke (target, args );
Long endTime = System. currentTimeMillis ();
System. out. println ("[" + method. getName () + "] spend" + (endTime-beginTime) + "ms ");
Return obj;

}
});
}
}
}

Change the client call:


Package example;

Import java. util. List;
Import example. ProxyUtil. ArrayListProxy;

/**
*-----------------------------------------
* @ Description TODO
* @ Author fancy
* @ Mailbox fancydeepin@yeah.net
* @ Date 2012-8-27 <p>
*-----------------------------------------
*/
Public class ProxyApp {


Public static void main (String [] args ){

List <Integer> arrayListProxy = ArrayListProxy. PROXY. getInstance ();
ArrayListProxy. add (2 );
ArrayListProxy. add (4 );
System. out. println ("--------- iteration ---------");
For (int I: arrayListProxy ){
System. out. print (I + "\ t ");
}

}
}

Enum is used in the above Code. If you do not want to use enum, you can simply use a common class.

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.