The Java proxy pattern is implemented in the following ways:
1. Static proxy.
2.JDK Dynamic Agent.
3.CGLIB Dynamic Agent.
Example, there is an interface for greeting. There were two implementations, saying hello, and shaking hands. The code is as follows.
Interface:
Public Interface Greeting { publicvoid dogreet ();}
Implementation class:
Public class Implements Greeting { @Override publicvoid Dogreet () { System.out.println (" Greeting by say ' hello '. " ); }}
Public class Implements Greeting { @Override publicvoid Dogreet () { System.out.println ("Greeting by shake others ' s hands." ); }}
Public class Kisshello { publicvoid Dogreet () { System.out.println ("Greeting by Kiss. "); }}
If you do not change the code, you want to do some other things before and after you execute the target method. It can be implemented by proxy mode.
1. Static proxy. You need to create a proxy class. The proxy class implements the same interface as the target class, and the proxy class receives the target class object and tricks the implementation of the target class in the implementation method. As follows:
Public classGreetstaticproxyImplementsGreeting {Privategreeting hello;//by proxy object Publicgreetstaticproxy (Greeting hello) { This. hello=Hello; } @Override Public voidDogreet () {before ();//Perform other operations This. Hello.dogreet ();//Call the Target method after ();//Perform other actions} Public voidbefore () {System.out.println ("[Staticproxy] Come to someone."); } Public voidAfter () {System.out.println ("[Staticproxy] back to his own corner"); }}
Test Call:
Public classMain { Public Static voidMain (string[] args) {Greeting Hello=NewSayHello (); Greeting Shakehands=Newshakehands (); //Static proxyGreetstaticproxy statichelloproxy=Newgreetstaticproxy (hello); Statichelloproxy.dogreet (); System.out.println (); Greetstaticproxy Shakehandsproxy=NewGreetstaticproxy (shakehands); Shakehandsproxy.dogreet (); }
Operation Result:
' Hello ' . [ Staticproxy] Back to he own Corner[staticproxy] Come to someone. Greeting by shake others' s hands. [Staticproxy] Back to his own corner
There are drawbacks to this approach, and if an implementation class with N interfaces needs to be proxied, you need to create n proxy classes.
2.JDK Dynamic Agent
Create the proxy class as follows:
Public classJdkproxyImplementsInvocationhandler {PrivateObject Target; Publicjdkproxy (Object obj) { This. target=obj; } @Override Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {Object result=NULL; Before (); Result=Method.invoke (target, args); After (); returnresult; } Public voidbefore () {System.out.println ("[Jdkproxy] Come to someone."); } Public voidAfter () {System.out.println ("[Jdkproxy] back to his own corner"); }}
Test Call:
Public classMain { Public Static voidMain (string[] args) {Greeting Hello=NewSayHello (); Greeting Shakehands=Newshakehands (); //JDK Dynamic AgentJdkproxy dynamicproxy=Newjdkproxy (hello); Greeting Target=(greeting) proxy.newproxyinstance (Hello.getclass (). getClassLoader (), Hello.getclass (). Getinterfaces (), Dynamicproxy); Target.dogreet (); System.out.println (); } }
This is compared to the first way, although there is no need to create many proxy classes,
However, he relies on the need to implement interfaces with "proxied objects" that is: in the code example given above, dynamic proxies can proxy SayHello and shakehands, but cannot proxy kisshello. Because Kisshello does not implement an interface.
3.CGLIB Dynamic Agent.
To create a proxy class:
Public classCglibproxyImplementsMethodinterceptor { Public StaticCglibproxy proxy=NewCglibproxy (); PrivateCglibproxy () {} Public Staticcglibproxy getinstance () {returnproxy; } Public<T> T GetProxy (class<t>CLS) { return(T) enhancer.create (CLS, This); } @Override PublicObject Intercept (Object obj, Method method, object[] arg, methodproxy proxy)throwsthrowable {Object result=NULL; Try{before (); Result=proxy.invokesuper (obj, arg); After (); } Catch(Exception e) {e.printstacktrace (); } returnresult; } Public voidbefore () {System.out.println ("[Cglib] Come to someone."); } Public voidAfter () {System.out.println ("[Cglib] back to his own corner."); }}
Invocation Example:
Public class Main { publicstaticvoid main (string[] args) { // cglib Agent Greeting Targetproxy=cglibproxy.getinstance (). GetProxy (SayHello. Class); Targetproxy.dogreet (); System.out.println (); Cglibproxy.getinstance (). getinstance (). GetProxy (Kisshello. class ). Dogreet (); } }
In conclusion, the Cglib dynamic agent is best, and the spring framework also uses the Cglib package.
Three ways to implement Java proxies