Proxy Mode
The proxy pattern that exists in design mode; The role of proxy mode is to provide a proxy for other objects to control access to the object.
There are three roles in the proxy mode: Abstract role, Proxy role, real role, and three roles explained in Baidu Encyclopedia:
Abstract Role: A business method that declares the real role implementation through an interface or abstract class. Proxy Role: the implementation of abstract role, is the real role of the agent, through the real role of the business logic method to implement the abstract method, and can attach their own operations. Real role: Implement abstract roles, define the business logic that the real role will implement, and be called by the proxy role. The advantages of proxy mode: One is to hide the implementation of the delegate class (real role), and the other is to realize the decoupling between the client and the delegate class;agents in Java
In Java, proxy static agent and dynamic agent, the so-called static agent is in the program before the proxy class already exist, generally this kind of proxy class is through our own definition of Java class to implement; Dynamic agent is relatively troublesome, is to generate proxy classes when the program runs; is generated dynamically through our Java code;
Now there is a scene: railway station ticketing, some agents can also buy tickets, where the train ticket agent is the role of agent;
first, the selling ticket is abstracted into an interface:
Public Interface Iticketservice { void sellticket (String name);}
Train station to sell tickets implement this interface:
Public class Implements Iticketservice { publicvoid sellticket (String name) { + "successfully purchased a ticket") ; }}
Static proxy
Static proxy is in Java code we define the proxy class, the proxy class holds the reference of the delegate class, and the proxy class also implements the same interface as the delegate class;
Public classStationproxyImplementsIticketservice {PrivateIticketservice Ticketservice; Publicstationproxy (Iticketservice ticketservice) { This. Ticketservice =Ticketservice; } Public voidSellticket (String name) {System.out.println ("Consignment Point starts selling tickets"); This. Ticketservice.sellticket (name); System.out.println ("Sell your tickets for success."); }}
From the code we can see the advantages of the agent, the agent inside or call the method of the delegate class, we call the method of the delegate class before or after the method can be used to do some related operations;
The invocation of static proxies is also very simple:
Iticketservice ticketservice=New trainstation (); stationproxystation =new Stationproxy (Ticketservice); station. Sellticket ("Zhang San");
Output:
Sell Point start selling tickets
Zhang San successfully purchased a ticket
Sell your tickets for a successful sale.
Dynamic Agent
The difference between a dynamic agent and a static proxy is that the proxy class is generated at runtime, and the advantage of dynamic agent is that it can conveniently manage the function of the proxy class, instead of modifying the agent function one by one, when the agent is very many, the advantage of the dynamic agent is much bigger;
Invocationhandler
When using dynamic proxies, we need to define a proxy class and the associated mediation class between the delegate class, in Java, this intermediary class should implement the Invocationhandler interface;
Public Interface Invocationhandler { public object Invoke (Object proxy, Method method, object[] args) throws Throwable;}
In the Invocationhandler interface there is only one in Voke method, when the proxy class execution proxy method will be executed by the Invoke method; Proxy: Agent Class object, method needs to execute proxy methods The args proxy method executes the arguments, The return value of the method object is the return value of the proxy method , we can add the unified processing logic in the in Voke method; We can create dynamic proxy classes, for example, for train ticket sales.
Public classDynamicproxyImplementsInvocationhandler {PrivateIticketservice Ticketservice; Publicdynamicproxy (Iticketservice ticketservice) { This. Ticketservice=Ticketservice; } @Override PublicObject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Dynamic agent starts selling tickets"); Object obj=Method.invoke (Ticketservice,args); System.out.println ("Dynamic agent Sell ticket end"); returnobj; }}
From the Dynamicproxy class, our proxy class also holds an instance of the delegate class, which uses reflection to execute the method in invoke;
A dynamic proxy class that implements the Invocationhandler interface in Java requires a proxy to obtain an instance
Dynamicproxy dynamicproxy=New dynamicproxy (ticketservice); Class<?>[] interfaces=new class<?>[]{iticketservice. Class}; System.getproperties (). Put ("Sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); Iticketservice ticketproxy= (iticketservice) proxy.newproxyinstance (iticketservice. Class. getClassLoader (), interfaces,dynamicproxy); Ticketproxy. Sellticket ("John Doe");
An instance of the proxy class is obtained by Newproxyinstance in the proxy class;
Public Static Object newproxyinstance (ClassLoader loader, Class<?>[] interfaces,invocationhandler h)
In the Newproxyinstance method ClassLoader is the proxy load class, the interfacess array is an array of interfaces implemented by the class, and H is our own defined mediation class.
through System.getproperties (). Put ("Sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); The method generates a $proxy0.class file, which is a dynamically generated proxy class file;
We can look at the generated proxy class:
ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy;Importjava.lang.reflect.UndeclaredThrowableException; Public Final class$Proxy 0extendsProxyImplementsIticketservice {Private StaticMethod M1; Private StaticMethod m2; Private StaticMethod m3; Private StaticMethod M0; Public$Proxy 0 (Invocationhandler var1)throws { Super(VAR1); } Public Final BooleanEquals (Object var1)throws { Try { return((Boolean)Super. H.invoke ( This, M1,Newobject[]{var1})). Booleanvalue (); } Catch(RuntimeException |Error Var3) { ThrowVar3; } Catch(Throwable var4) {Throw Newundeclaredthrowableexception (VAR4); } } Public FinalString toString ()throws { Try { return(String)Super. H.invoke ( This, M2, (object[])NULL); } Catch(RuntimeException |Error var2) { Throwvar2; } Catch(Throwable var3) {Throw Newundeclaredthrowableexception (VAR3); } } Public Final voidSellticket (String var1)throws { Try { Super. H.invoke ( This, M3,Newobject[]{var1}); } Catch(RuntimeException |Error Var3) { ThrowVar3; } Catch(Throwable var4) {Throw Newundeclaredthrowableexception (VAR4); } } Public Final intHashcode ()throws { Try { return(Integer)Super. H.invoke ( This, M0, (object[])NULL) . Intvalue (); } Catch(RuntimeException |Error var2) { Throwvar2; } Catch(Throwable var3) {Throw Newundeclaredthrowableexception (VAR3); } } Static { Try{M1= Class.forName ("Java.lang.Object"). GetMethod ("equals",NewClass[]{class.forname ("Java.lang.Object")}); M2= Class.forName ("Java.lang.Object"). GetMethod ("toString"),NewClass[0]); M3= Class.forName ("Iticketservice"). GetMethod ("Sellticket",NewClass[]{class.forname ("Java.lang.String")}); M0= Class.forName ("Java.lang.Object"). GetMethod ("Hashcode",NewClass[0]); } Catch(nosuchmethodexception var2) {Throw NewNosuchmethoderror (Var2.getmessage ()); } Catch(ClassNotFoundException var3) {Throw NewNoclassdeffounderror (Var3.getmessage ()); } }}
View Code
In the generated proxy class M3 is the Sellticket method of our interface definition, internal or call the Invoke method in the Invocationhandler interface;
Agents in Java