How to implement dynamic Agent in Java
Editor to share with you how to achieve dynamic agent Java, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to understand it!
Java dynamic agent
Prepare: maven dependency
Cglib cglib 3.2.5 javassist javassist 3.12.1.GA junit junit 3.8.1 test 1jdk implementation
Dynamic proxies in jdk mode need to be implemented by implementing interfaces, so first create a simple interface and implementation class:
Interface:
Package per.ym.proxy.jdk;public interface BookStore {String add (String bookName); String delete (String bookName);}
Implementation class:
Package per.ym.proxy.jdk;public class BookStoreImpl implements BookStore {public String add (String bookName) {System.out.println ("add Books:" + bookName); return bookName;} public String delete (String bookName) {System.out.println ("remove Books:" + bookName); return bookName;}}
Create a proxy class factory:
Package per.ym.proxy.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class BookStoreJdkProxyFactory implements InvocationHandler {private BookStore bookStroe; public BookStoreJdkProxyFactory (BookStore bookStore) {this.bookStroe = bookStore;} public BookStore getProxy () {return (BookStore) Proxy.newProxyInstance (bookStroe.getClass () .getClassLoader (), bookStroe.getClass () .getInterfaces (), this) } public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {System.out.println ("calling method: + method.getName ()); String bookName = (String) method.invoke (bookStroe, args); System.out.println (" method: + method.getName () + "execution complete"); return bookName;}}
Test class:
Package per.ym.proxy.jdk;public class TestMain {public static void main (String [] args) {/ / Save the generated proxy class to a file System.getProperties () .put ("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); BookStoreJdkProxyFactory factory = new BookStoreJdkProxyFactory (new BookStoreImpl ()); BookStore proxy = factory.getProxy (); proxy.add ("thinking in java") Proxy.delete ("spring in action");}}
Test results:
Call method: add add books: thinking in java method: add execution completed call method: delete delete books: spring in action method: delete execution completed
Generate the proxy class file under the project directory:
< clazzs.length ; i++) { if (paraSb1.length() >
1) {paraSb1.append (",") .append (arg [I]. GetName ()) .append ("). Append (" arg "+ I); paraSb2.append (", "). Append (" arg "+ I);} else {paraSb1.append (clazzs [I]. GetName ()) .append ("). Append ("arg" + I) ParaSb2.append ("arg" + I);}} paraSb1.append (")"); paraSb2.append (")"); methodSb.append (paraSb1); clazzs = m.getExceptionTypes (); if (clazzs.length > 0) {methodSb.append ("throws"); for (int iTun0) I
< clazzs.length; i++) { if (exceptionSb.length() >0) {exceptionSb.append (",") .append (getName [I] .append ();} else {exceptionSb.append (clazzs.getName () } methodSb.append ("{") .append ("System.out.println (\" execution method: "+ m.getName () +"\ "" + ");) .append (m.getReturnType (). GetName () +" result = bookStore. "+ m.getName () + paraSb2 +" ") .append (" System.out.println (\ "method:" + m.getName () + "execution completed\"); ") .append (" return result; ") .append ("} "); / / add a method to the generated proxy class ctClass.addMethod (CtNewMethod.make (methodSb.toString (), ctClass)) MethodSb.delete (0, methodSb.length ()); paraSb1.delete (0, paraSb1.length ()); paraSb2.delete (0, paraSb2.length ()); exceptionSb.delete (0, exceptionSb.length ());} / / Save the generated class information to the file ctClass.writeFile (); / / get the proxy class class object Class clazz = ctClass.toClass () Return clazz.newInstance ();} private static String getModifier (int modifier) {switch (modifier) {case 0: return "protected"; case 1: return "public"; case 2: return "private"; case 4: return "" Default: return "public";}}
Test class:
Package per.ym.proxy.javassist;public class TestMain {public static void main (String [] args) throws Exception {BookStore proxy = BookStoreJavassistProxyFactory.getProxy (); proxy.add ("thinking in java"); proxy.delete ("spring in action");}}
Test results:
Execution method: add add books: thinking in java method: add execution completed execution method: delete delete books: spring in action method: delete execution complete
The generated proxy class class file:
Decompiled generated proxy class (formatted):
Package per.ym.proxy.javassist;import java.io.PrintStream;public class BookStoreProxy extends BookStore {private BookStore bookStore = new BookStore (); public String add (String paramString) {System.out.println ("execution method: add"); String str = this.bookStore.add (paramString); System.out.println ("method: add execution completed"); return str;} public String delete (String paramString) {System.out.println ("execution method: delete") String str = this.bookStore.delete (paramString); System.out.println ("method: delete execution completed"); return str;}}
I don't know why the method parameter name is paramString instead of the arg0 I set?
The above is all the content of the article "how to achieve dynamic proxy in Java". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!