Get the App
SLTechnology News&Howtos  ›  Development  › 

How to implement dynamic Agent in Java

Shulou Source: shulou.com Published: 2022-06-02 11:37:40 10月02日 Update

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!

Tags: Methods agents generation books information dynamic files tests parameters interfaces methods factories directories articles results compilations content objects more uncomfortable Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno vpn OPPO Reno MariaDB Redmi macOS