Talk about Java proxy mode

Source: Internet
Author: User
Tags throwable

Proxy implementations can be classified as static agents and dynamic proxies.

Static proxy

Static proxy mode is actually very common, such as buy train tickets This small thing: The ox is equivalent to the station agent, we can buy tickets through the ox, but only to the railway station for change and refund. In the code implementation is equivalent to a delegate object Realsubject provide a proxy object proxies, through proxy can call Realsubject part of the function, and add some additional business processing, while masking the Realsubject open interface.


1, Realsubject is the delegate class, Proxy is the agent class;
2, Subject is the interface of the delegate class and the proxy class;
3. Request () is a common method of entrusting class and proxy class;

The specific code is implemented as follows:

InterfaceSubject {voidRequest();}ClassRealsubjectImplementsSubject {PublicvoidRequest() {System.out.println ("Realsubject"); }}ClassProxyImplementsSubject {Private Subject Subject;PublicProxy (Subject Subject) {this.subject = Subject;} public void  Request () {System.out.println ( "Begin"); Subject.request (); System.out.println ( "end");}} public class proxytest {public static void main ( String args[]) {realsubject subject = new realsubject (); Proxy p = new Proxy (subject); P.request ();}}         

In a static proxy implementation, a delegate class corresponds to a proxy class, and the proxy class is determined during compilation.

Dynamic Agent

Dynamic agent, the proxy class is not implemented in the Java code, but in the runtime generation, compared to static proxy, dynamic agent can be very convenient to delegate class method of unified processing, such as adding method calls, add log function and so on, dynamic agent is divided into JDK dynamic agent and Cglib dynamic agent, Here's an example of how to implement a JDK dynamic proxy.

1. Define Business logic

public  Interface service {//target method public abstract void add (); public class userserviceimpl implements Service { public void add () {System.out.println ( "this is Add Service "); } } 

2, java.lang.reflect.Proxy the use of classes and java.lang.reflect.InvocationHandler interfaces to define the implementation of the proxy class.

ClassMyinvocatiohandlerImplementsInvocationhandler {Private Object target;PublicMyinvocatiohandler(Object target) {This.target = target; }@OverridePublic Object invoke(object proxy, Method method, object[] args) throws Throwable {System.out.println (
                     
                       "-----Before-----"); Object result = Method.invoke (target, args); System.out.println (
                      "-----End-----"); return result;} //Generate proxy Object public object  getproxy() {ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader (); Class<?>[] interfaces = Target.getclass (). Getinterfaces (); return Proxy.newproxyinstance (loader, interfaces, this );}}        
                     

3. Using Dynamic Agent

public class ProxyTest {    public static void main(String[] args) { Service service = new UserServiceImpl(); MyInvocatioHandler handler = new MyInvocatioHandler(service); Service serviceProxy = (Service)handler.getProxy(); serviceProxy.add(); }}

Execution Result:

-----before-----This is add service-----end-----

The generation process of proxy objects is implemented by the Newproxyinstance method of the proxy class, which is divided into 3 steps:
1, the ProxyGenerator.generateProxyClass method is responsible for generating the byte code of the proxy class, generating logic is more complex, interested students can continue to analyze the source sun.misc.ProxyGenerator;

// proxyName:格式如 "com.sun.proxy.$Proxy.1";// interfaces:代理类需要实现的接口数组;// accessFlags:代理类的访问标识;byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);

2, the native method Proxy.defineClass0 is responsible for the implementation of bytecode loading, and return the corresponding class object.

Class clazz = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);

3, using clazz.newInstance the reflection mechanism to generate the object of the proxy class;

Anti-compilation proxy class
In order to understand the dynamic proxy more clearly, the proxy class bytecode is generated by the following method.

byte[] classFile = ProxyGenerator.generateProxyClass("com.sun.proxy.$Proxy.1", service.getClass().getInterfaces());FileOutputStream out = new FileOutputStream("com.sun.proxy.$Proxy.1.class");out.write(classFile);out.flush();

Use the Anti-compilation tool Jad jad com.sun.proxy.$Proxy.1 to see how the proxy class is implemented, and the compiled Java code is as follows:

PublicFinalClass $Proxy1ExtendsProxyImplementsService {Public $proxy 1 (invocationhandler invocationhandler) {Super (Invocationhandler); }PublicFinalBooleanequals(Object obj) {try {Return ((Boolean)Super.h.invoke (This, M1,New object[] {obj}). Booleanvalue (); }catch (Error _ex) {}catch (Throwable throwable) {ThrowNew Undeclaredthrowableexception (Throwable); } }PublicFinal StringTostring() {try {Return (String)Super.h.invoke (This, M2,NULL); }catch (Error _ex) {}catch (Throwable throwable) {ThrowNew Undeclaredthrowableexception (Throwable); } }PublicFinalvoidAdd() {try {Super.h.invoke (This, M3,NULL);Return }catch (Error _ex) {}catch (Throwable throwable) {ThrowNew Undeclaredthrowableexception (Throwable); } }PublicFinalIntHashcode() {try {Return ((Integer)Super.h.invoke (This, M0,NULL). Intvalue (); }catch (Error _ex) {}catch (Throwable throwable) {ThrowNew Undeclaredthrowableexception (Throwable); } }PrivateStatic Method M1;Privatestatic Method m2;PrivateStatic Method m3;PrivateStatic Method M0;static {try {m1 = Class.forName ("Java.lang.Object"). GetMethod ("Equals",New class[] {class.forname ("Java.lang.Object")}); M2 = Class.forName ("Java.lang.Object"). GetMethod (  "toString", new class[0]); m3 = Class.forName ( "zzzzzz. Service "). GetMethod (" add ", new class[ 0]); M0 = Class.forName ( "Hashcode", new class[0]);} catch (nosuchmethodexception nosuchmethodexception) {throw Span class= "Hljs-keyword" >new Nosuchmethoderror (Nosuchmethodexception.getmessage ()); } catch (classnotfoundexception classnotfoundexception) { Throw new Noclassdeffounderror (Classnotfoundexception.getmessage ());}}}    

From the above code can be found:
1, the generated $proxy1 inherits from the proxy class, and implements the service interface.
2, the method of executing the proxy object is actually executing the Invocationhandle object's Invoke method, the passed parameter is the current proxy object, the current execution method and the parameter.

super.h.invoke(this, m3, null);

Limitations of JDK Dynamic proxy usage
The Proxy InvocationHandler JDK dynamic Proxy implemented through the reflection class and callback interface requires that the delegate class must implement an interface, but in fact not all classes have interfaces, and for classes that do not implement an interface, dynamic proxies cannot be implemented using that side of the way.



Paper/small Wolf (writer of Jane's book)
Original link: http://www.jianshu.com/p/a1d094fc6c00
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".

Talk about Java 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.