What is dynamic proxy: In fact, STRUTS2 action request is also used dynamic proxy, such as action need to call a lot of interceptors, but if you use the action instance to one by one call interceptor, is not good trouble, and the code coupling is very high, So can I automatically generate a dynamic proxy object for each action, and let this object replace the action instance to work, the answer is yes,
The principle of the proxy design pattern: Use a proxy to wrap the object, and then replace the original object with the proxy object. Any calls to the original object are passed through the proxy. The proxy object determines whether and when the method call is forwarded to the original object.
How to implement the dynamic agent?
Let's take a look at the specific steps below:
1 Creating a specific business logic class
2 Set up the Proxy object class and wrap the business logic class in
3 get the object that needs to be proxied, (generally in the construction method to get, in addition to write method to get also can)
4 Returns the proxy object (actually the same object as the object that needs the proxy, but the name is not the same, and if you don't believe it, you can test whether they hashcode the same),
Use the Proxy.newproxyinstance (loader, interfaces, h) method to return a proxy object:
Proxy.newproxyinstance (loader, interfaces, h) Parameter Description loader: The class loader used by the proxy object. ClassLoader Loader=target.getclass (). getClassLoader (); Interfaces: Specifies the type of proxy object. Which methods are available in the Proxy proxy object. Class[] Interfaces=new Class[]{haveproxyobject.class} h: How to respond when invoking the method of a proxy object, in effect invoking the Invoke method of Invocationhandler
Invocationhandler h=New Invocationhandler () { public object Invoke (Object proxy, method, Object[] args) {} parameter Description Proxy: proxy object. This object is not normally used in the Invoke method to avoid being trapped in a dead loop method: The way that is being called, and also springaop the connection point, args: The arguments passed in by the calling method, that is, the call to the business logic class Arguments passed when the method is
The 5InvocationHandler Invoke () method implements the functions that need to be implemented before and after invoking a method that requires a proxy object (that is, the business logic Class)
Specific implementation code:
The first step is to create a logic class:
PackageCom.jeremy.spring.InvocationHandler; Public classArithmeticcalculatorimplImplementsArithmeticcalculator {@Override Public intAddintIintj) {intResult =i+J; System.out.println ( This. GetClass () + "" + This. Hashcode ());//Just test whether it is the same objectreturnresult; } @Override Public intSubintIintj) {intResult =i-J; returnresult; } @Override Public intMulintIintj) {intResult =i*J; returnresult; } @Override Public intDivintIintj) {intResult =i/J; returnresult; }}
Step two--step fifth:
PackageCom.jeremy.spring.InvocationHandler;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy; Public classArithmeticcalculatorproxy {
Second Step package business logic classPrivateArithmeticcalculator target=NULL; /** Use the construction method to pass the object to be proxied (third step obtains the object that needs the proxy)*/ Publicarithmeticcalculatorproxy (Arithmeticcalculator arithmeticcalculator) { This. target=Arithmeticcalculator; } /** Returns the proxy object, (the fourth step obtains the proxy object, uses the Proxy.newproxyinstance () method) namely returns the Arithmeticcalculator object, why should return?? */ Publicarithmeticcalculator Getloggingproxy () {Arithmeticcalculator proxy=NULL; ClassLoader Loader=Target.getclass (). getClassLoader (); Class[] Interfaces=NewClass[]{arithmeticcalculator.class};
The fifth step uses the Invacatiohandler invoke () method to implement the functions required before and after invoking the business logic class Invocationhandler H=NewInvocationhandler () {@Override Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {Object result=NULL;
result = Method.invoke (target, args);//method.invoke (): The method is to execute the method of the logical class return result; } }; /** * Loader: the class loader used by the proxy object. * Interfaces: Specifies the type of proxy object. Which methods are available in the Proxy proxy object. * H: When invoking the method of a proxy object, how to respond is actually called the Invoke method of Invocationhandler */ proxy = (Arithmeticcalculator) PROXY.NEWP Roxyinstance (loader, interfaces, h); System.out.println (Proxy.getclass () + "" +proxy.hashcode ());//Just to test whether it is the same object return proxy; }}
Test code:
@Test publicvoid Test () { arithmeticcalculator Aimpl=New Arithmeticcalculatorimpl (); Aimpl=new arithmeticcalculatorproxy (Aimpl). Getloggingproxy (); int Result=aimpl.add (1, 2); SYSTEM.OUT.PRINTLN (result); }
Test results:
Class $Proxy 4 9856161
Class Com.jeremy.spring.InvocationHandler.ArithmeticCalculatorImpl 9856161
3
Dynamic Agent for Java