[SSM] 15 - Summary of the use of dynamic agent mode

catalogue

1, Agent mode

2, Static proxy

(1) Static proxy

(2) Simple implementation of static agent

3, Dynamic agent

(1) Dynamic agent

(2) Simple implementation of dynamic agent

4, Principle analysis of dynamic agent

5, InvocationHandler interface and Proxy class

6, Comparison and summary of JDK dynamic agent and CGLIB dynamic agent code examples

(1) Define and create user management interface

(2) User management implementation class, which implements the user management interface (the implementation class of the proxy)

(3) JDK agent implementation: JDK dynamic agent implements InvocationHandler interface

(4) CGLIB agent is adopted for implementation: the asm version package needs to be imported to implement the MethodInterceptor interface

(5) Client call test and results

(6) JDK and CGLIB dynamic agent summary

Reference books, literature and materials

1, Agent mode

Proxy mode is a commonly used java design mode. Its feature is that the proxy class has the same interface with the delegate class. The proxy class is mainly responsible for preprocessing messages for the delegate class, filtering messages, forwarding messages to the delegate class, and post-processing messages. There is usually an association relationship between proxy class and delegate class. The object of a proxy class is associated with the object of a delegate class. The object of the proxy class itself does not really realize the service, but provides a specific service by calling the relevant methods of the object of the delegate class. In short, when accessing the actual object, we access it through the proxy object. The proxy mode introduces a certain degree of indirectness when accessing the actual object, because this indirectness can be added for a variety of purposes.

2, Static proxy

(1) Static proxy

Static proxy: it is created by programmers or automatically generated by specific tools, that is, the interface, proxy class and proxy class have been determined at compile time. The name of the proxy class before the program runs The class file has been generated.

(2) Simple implementation of static proxy

According to the class diagram of the agent mode above, write a simple example of static agent: if a classmate wants to pay the class fee to the teacher, but they all pass their money to the teacher through the monitor. Here, the monitor acts as an agent for students to pay class fees, and the monitor is the agent of students.

  • 1. Determine the specific behavior of creating an interface

First, we create a Person interface. This interface is the public interface for students (proxy class) and monitor (proxy class). They all have the behavior of paying shift fees. In this way, the class fee for students can be implemented by the monitor.

   
  1. /**
  2. * Create Person interface
  3. */
  4. public interface Person {
  5. //Turn in the shift fee
  6. void giveMoney ();
  7. }
  • 2. The proxy object implements the interface and completes the specific business logic

The student class implements the Person interface. Student can specifically implement the action of shift handover fee:

   
  1. public class Student implements Person {
  2. private String name;
  3. public Student (String name) {
  4. this.name = name;
  5. }
  6. @Override
  7. public void giveMoney () {
  8. System.out.println(name + "Shift handover fee: 50 yuan");
  9. }
  10. }
  • 3. The agent class implements the interface to complete the pre-processing messages, filtering messages, forwarding messages to the delegate class, and post-processing messages of the delegate class.

StudentsProxy class, which also implements the Person interface, but also holds a student class object. Since the Peson interface is implemented and a student object is held at the same time, he can execute the shift fee (execute the giveMoney() method) on behalf of the student object.

   
  1. /**
  2. * The student agent class also implements the Person interface to save a student entity, which can act as a proxy for students
  3. * @author Gonjan
  4. *
  5. */
  6. public class StudentsProxy implements Person{
  7. //Represented student
  8. Student stu;
  9. public StudentsProxy (Person stu) {
  10. // Delegate student objects only
  11. if(stu.getClass() == Student.class) {
  12. this.stu = (Student)stu;
  13. }
  14. }
  15. //Delegate the shift fee and call the shift fee behavior of the delegated student
  16. public void giveMoney () {
  17. stu.giveMoney();
  18. }
  19. }
  • 4. Client operation and analysis
   
  1. public class StaticProxyTest {
  2. public static void main (String[] args) {
  3. //Zhang San, the student being represented, handed over his class fee to the agent monitor (monitor) for completion
  4. Person zhangsan = new Student( "Zhang San");
  5. //Generate a proxy object and pass Zhang San to the proxy object
  6. Person monitor = new StudentsProxy(zhangsan);
  7. //Shift handover fee for the agent of the monitor
  8. monitor.giveMoney();
  9. }
  10. }

Instead of directly implementing the shift fee through Zhang San (the agent), it is implemented through the monitor (the agent). This is the agent mode.

The most important thing of proxy mode is to have a public interface (Person), a specific class (Student) and a proxy class (StudentsProxy). The proxy class holds the instance of the specific class and executes the instance method of the specific class on its behalf. As mentioned above, the proxy mode introduces a certain degree of indirection when accessing actual objects, because this indirection can be used for a variety of purposes. The indirectness here means that we do not directly call the methods of the actual object, so we can add some other uses in the proxy process. For example, before joining the monitor to help Zhang San pay the shift fee, I want to reflect that Zhang San has made great progress in his recent study, which can be easily achieved through the agent mode:

   
  1. public class StudentsProxy implements Person{
  2. //Represented student
  3. Student stu;
  4. public StudentsProxy (Person stu) {
  5. // Delegate student objects only
  6. if(stu.getClass() == Student.class) {
  7. this.stu = (Student)stu;
  8. }
  9. }
  10. //Delegate the shift fee and call the shift fee behavior of the delegated student
  11. public void giveMoney () {
  12. System.out.println( "Zhang San has made progress in his study recently!");
  13. stu.giveMoney();
  14. }
  15. }

You only need to perform other operations before helping Zhang San pay the shift fee in the agent class. This operation is also a great advantage of using proxy mode. The most straightforward is aspect oriented programming (AOP) in Spring. We can perform some operations before and after a pointcut. This pointcut is a method. The class of these methods must be proxied, and some other operations are cut in during the proxy process. In fact, it is also the main idea of cross-sectional thinking. A blog will be published later, and examples of how to use it. The idea is to verify the access parameters of the controller layer and necessary operations. There are many such examples in the Spring source code, and there will be time to sort them out later.

3, Dynamic agent

(1) Dynamic agent

The proxy method created by the proxy class when the program is running is called dynamic proxy.

In our static proxy example above, the proxy class (studentProxy) is self-defined and has been compiled before the program runs. However, the dynamic proxy class is not defined in Java code, but dynamically generated at runtime according to our "instructions" in Java code. Compared with static proxy, the advantage of dynamic proxy is that it can easily handle the functions of proxy classes in a unified way without modifying the methods in each proxy class. For example, you want to add a processing method before each agent's method:

   
  1. public void giveMoney () {
  2. //Add processing method before calling the proxy method
  3. beforeMethod();
  4. stu.giveMoney();
  5. }

There is only one giveMoney method here. Write the beforeMethod method method once, but if there are many other methods besides giveMoney, you need to write the beforeMethod method method many times, which is troublesome. Therefore, it is recommended to use dynamic proxy implementation.

(2) Simple implementation of dynamic agent

In java Lang.reflect package provides a Proxy class and an InvocationHandler interface, through which JDK dynamic Proxy classes and dynamic Proxy objects can be generated.

  • 1. Determine the specific behavior of creating an interface

First, we create a Person interface. This interface is the public interface for students (proxy class) and monitor (proxy class). They all have the behavior of paying shift fees. In this way, the class fee for students can be implemented by the monitor.

   
  1. /**
  2. * Create Person interface
  3. */
  4. public interface Person {
  5. //Turn in the shift fee
  6. void giveMoney ();
  7. }
  • 2. The proxy object implements the interface and completes the specific business logic (some methods are added here for detection, and dynamic proxy is used later for differentiation)

The Student class implements the Person interface.

   
  1. public class Student implements Person {
  2. private String name;
  3. public Student (String name) {
  4. this.name = name;
  5. }
  6. @Override
  7. public void giveMoney () {
  8. try {
  9. //Suppose it took a second to count the money
  10. Thread.sleep( 1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. System.out.println(name + "Shift handover fee: 50 yuan");
  15. }
  16. }

A tool class for detecting execution time is defined. The start method is invoked before any method is executed. After the execution of the finsh method, the running time of the method can be calculated. This is also the simplest method of execution time detection.

   
  1. public class MonitorUtil {
  2. private static ThreadLocal<Long> tl = new ThreadLocal<>();
  3. public static void start () {
  4. tl.set(System.currentTimeMillis());
  5. }
  6. //Printing time at end
  7. public static void finish (String methodName) {
  8. long finishTime = System.currentTimeMillis();
  9. System.out.println(methodName + "Method time consuming" + (finishTime - tl.get()) + "ms");
  10. }
  11. }
  • 3. The agent class implements the interface to complete the pre-processing messages, filtering messages, forwarding messages to the delegate class, and post-processing messages of the delegate class.

Create StuInvocationHandler class and implement InvocationHandler interface. This class holds an instance target of the proxy object. There is an invoke method in InvocationHandler. All methods that execute proxy objects will be replaced with the invoke method. Execute the corresponding method of the proxy object target in the invoke method. In the proxy process, we add our own other processing before actually executing the methods of the proxy object. This is also the main principle of AOP implementation in Spring. It also involves a very important basic knowledge about java reflection.

   
  1. public class StuInvocationHandler<T> implements InvocationHandler {
  2. //Proxied object held by invocationHandler
  3. T target;
  4. public StuInvocationHandler (T target) {
  5. this.target = target;
  6. }
  7. /**
  8. * proxy:Represents a dynamic proxy object
  9. * method: Represents the method being executed
  10. * args: Represents the argument passed in when the target method is called
  11. */
  12. @Override
  13. public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
  14. System.out.println( "Agent execution" +method.getName() + "method");
  15. //The monitoring method is inserted in the agent process, and the calculation of this method is time-consuming
  16. MonitorUtil.start();
  17. Object result = method.invoke(target, args);
  18. MonitorUtil.finish(method.getName());
  19. return result;
  20. }
  21. }
  • 4. Client operation and analysis
   
  1. public class ProxyTest {
  2. public static void main (String[] args) {
  3. //Create an instance object, which is the proxy object
  4. Person zhangsan = new Student( "Zhang San");
  5. //Create an InvocationHandler associated with the proxy object
  6. InvocationHandler stuHandler = new StuInvocationHandler<Person>(zhangsan);
  7. //Create a proxy object stuProxy to proxy zhangsan. Each execution method of the proxy object will replace the invoke method in the Invocation
  8. Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
  9. //Method of executing shift fee by agent
  10. stuProxy.giveMoney();
  11. }
  12. }

Zhang San created a student who needs to be proxied and passed the zhangsan object to stuHandler. When we created the proxy object stuProxy, we took stuHandler as a parameter. As mentioned above, all methods executing the proxy object will be replaced with the invoke method, that is, the invoke method in StuInvocationHandler will be executed finally.

The advantage of dynamic proxy is that it can easily handle the functions of proxy classes uniformly without modifying the methods in each proxy class. Because all the methods executed by the proxy are called through the invoke method in the InvocationHandler, we can perform the same operation on all the proxy methods as long as we handle them uniformly in the invoke method. For example, in the method timing here, all the methods executed by the proxy object will be timed. However, I only made a small amount of code.

The process of dynamic proxy and the relationship between proxy object and proxy object are not as clear and clear as static proxy. Because in the process of dynamic proxy, we don't actually see the proxy class, nor do we clearly see the specific appearance of the proxy class. In addition, the proxy object and proxy object in dynamic proxy are completed through InvocationHandler. What's the specific operation, Why do all methods executed by proxy objects execute through the invoke method in InvocationHandler. With these problems, we need to briefly analyze the source code of java Dynamic agent to find out the reason.

4, Principle analysis of dynamic agent

We use the newProxyInstance method of Proxy class to create a dynamic Proxy object. Looking at the source code of this method, we find that it only encapsulates the steps of creating a dynamic Proxy class:

   
  1. public static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces,
  2. InvocationHandler h) throws IllegalArgumentException {
  3. Objects.requireNonNull(h);
  4. final Class<?>[] intfs = interfaces.clone();
  5. final SecurityManager sm = System.getSecurityManager();
  6. if (sm != null) {
  7. checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
  8. }
  9. /*
  10. * Look up or generate the designated proxy class.
  11. */
  12. Class<?> cl = getProxyClass0(loader, intfs);
  13. /*
  14. * Invoke its constructor with the designated invocation handler.
  15. */
  16. try {
  17. if (sm != null) {
  18. checkNewProxyPermission(Reflection.getCallerClass(), cl);
  19. }
  20. final Constructor<?> cons = cl.getConstructor(constructorParams);
  21. final InvocationHandler ih = h;
  22. if (!Modifier.isPublic(cl.getModifiers())) {
  23. AccessController.doPrivileged( new PrivilegedAction<Void>() {
  24. public Void run () {
  25. cons.setAccessible( true);
  26. return null;
  27. }
  28. });
  29. }
  30. return cons.newInstance( new Object[]{h});
  31. } catch (IllegalAccessException|InstantiationException e) {
  32. throw new InternalError(e.toString(), e);
  33. } catch (InvocationTargetException e) {
  34. Throwable t = e.getCause();
  35. if (t instanceof RuntimeException) {
  36. throw (RuntimeException) t;
  37. } else {
  38. throw new InternalError(t.toString(), t);
  39. }
  40. } catch (NoSuchMethodException e) {
  41. throw new InternalError(e.toString(), e);
  42. }
  43. }

The focus is on these four locations:

   
  1. final Class<?>[] intfs = interfaces.clone();
  2. Class<?> cl = getProxyClass0(loader, intfs);
  3. final Constructor<?> cons = cl.getConstructor(constructorParams);
  4. return cons.newInstance( new Object[]{h});

The most important thing to pay attention to is "class <? > cl = getProxyClass0(loader, intfs); In this sentence, the proxy class is generated here, and the constructor in the following code is also obtained through the class generated here. It can be seen that the generation of this class is the key to the whole dynamic proxy. Because it is a dynamically generated class file, I will not specifically analyze how to generate this class file here, but only need to know that this class file is stored in the java virtual machine, We can print it into the file by the following methods to see the true face:

   
  1. byte[] classFile = ProxyGenerator.generateProxyClass( "$Proxy0",Student.class.getInterfaces());
  2. String path = "G:/javacode/javase/Test/bin/proxy/StuProxy.class";
  3. try( FileOutputStream fos = new FileOutputStream(path)) {
  4. fos.write(classFile);
  5. fos.flush();
  6. System.out.println( "proxy class class File written successfully");
  7. } catch (Exception e) {
  8. System.out.println( "Write file error");
  9. }

Decompile this class file. Let's see what jdk generates for us:

   
  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4. import java.lang.reflect.UndeclaredThrowableException;
  5. import proxy.Person;
  6. public final class $Proxy0 extends Proxy implements Person {
  7. private static Method m1;
  8. private static Method m2;
  9. private static Method m3;
  10. private static Method m0;
  11. /**
  12. *Note that this is the construction method of generating proxy class. The method parameter is InvocationHandler type. Do you understand this
  13. *Why does the proxy object always execute the invoke method in the InvocationHandler, and the InvocationHandler holds one
  14. *The instance of the proxy object can't help but wonder if it is? Yes, that's what you think.
  15. *
  16. *super(paramInvocationHandler),Is the constructor that calls the parent class Proxy.
  17. *Parent class holding: protected InvocationHandler h;
  18. *Proxy Construction method:
  19. * protected Proxy(InvocationHandler h) {
  20. * Objects.requireNonNull(h);
  21. * this.h = h;
  22. * }
  23. *
  24. */
  25. public $Proxy0(InvocationHandler paramInvocationHandler)
  26. throws
  27. {
  28. super(paramInvocationHandler);
  29. }
  30. //This static block was originally at the end. I brought it to the front for easy description
  31. static
  32. {
  33. try
  34. {
  35. //Look at what's in the static block here. Did you find the giveMoney method. Remember the name given by giveMoney through reflection m3, and ignore the others first
  36. m1 = Class.forName( "java.lang.Object").getMethod( "equals", new Class[] { Class.forName( "java.lang.Object") });
  37. m2 = Class.forName( "java.lang.Object").getMethod( "toString", new Class[ 0]);
  38. m3 = Class.forName( "proxy.Person").getMethod( "giveMoney", new Class[ 0]);
  39. m0 = Class.forName( "java.lang.Object").getMethod( "hashCode", new Class[ 0]);
  40. return;
  41. }
  42. catch (NoSuchMethodException localNoSuchMethodException)
  43. {
  44. throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
  45. }
  46. catch (ClassNotFoundException localClassNotFoundException)
  47. {
  48. throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
  49. }
  50. }
  51. /**
  52. *
  53. *Here, the giveMoney method of the proxy object is called, which directly calls the invoke method in the InvocationHandler and passes m3 in.
  54. *this.h.invoke(this, m3, null);It's simple and clear.
  55. *Now, think again, the proxy object holds an InvocationHandler object, and the InvocationHandler object holds an object to be proxied,
  56. *Then contact the invoke method in the InvacationHandler. Well, that's it.
  57. */
  58. public final void giveMoney ()
  59. throws
  60. {
  61. try
  62. {
  63. this.h.invoke( this, m3, null);
  64. return;
  65. }
  66. catch (Error|RuntimeException localError)
  67. {
  68. throw localError;
  69. }
  70. catch (Throwable localThrowable)
  71. {
  72. throw new UndeclaredThrowableException(localThrowable);
  73. }
  74. }
  75. //Note that toString, hashCode and equals methods are omitted to save space. The principle is the same as the giveMoney method.
  76. }

jdk generates a proxy class named $Proxy0 (0 after this name is the number, and multiple proxy classes will increase at one time). This class file is placed in memory. When we create a proxy object, we obtain the construction method of this class through reflection, and then create a proxy instance. Through the view of the generated proxy class source code, we can easily see the specific process of dynamic proxy implementation.

We can think of InvocationHandler as an intermediary class, and the intermediary class holds a proxy object and invokes the corresponding method of the proxy object in the invoke method. Hold the reference of the proxy object through aggregation, and finally turn the external call to invoke into the call to the proxy object.

When the proxy class calls its own method, it calls the invoke method of the mediation class object through its own mediation class object, so as to achieve the proxy to execute the method of the proxy object. In other words, the dynamic agent realizes the specific agent function through the intermediary class.

Summary: the generated Proxy class: $Proxy0 extends Proxy implements Person. We can see that the Proxy class inherits the Proxy class, so it determines that the Java dynamic Proxy can only Proxy the interface. The inheritance mechanism of Java doomed these dynamic Proxy classes to be unable to implement the dynamic Proxy to the class. The above example of dynamic agent is actually a simple implementation of AOP. It is processed before and after the method of the target object is executed, and the time consumption of the method is counted. Spring's AOP implementation actually uses Proxy and InvocationHandler.

5, InvocationHandler interface and Proxy class

InvocationHandler interface is an interface implemented by the calling handler of proxy proxy instance. Each proxy instance has an associated calling handler; When a method is called by a proxy instance, the method call is encoded and dispatched to the invoke method of the calling handler.
See the description of InvocationHandler interface in the official document:

   
  1. {@code InvocationHandler} is the interface implemented by
  2.      the <i>invocation handler</i> of a proxy instance.
  3.      <p>Each proxy instance has an associated invocation handler.
  4.      When a method is invoked on a proxy instance, the method
  5.      invocation is encoded and dispatched to the {@code invoke}
  6.      method of its invocation handler.

When we call a method through a dynamic proxy object, the call of this method will be forwarded to the invoke method implementing the InvocationHandler interface class to call, as shown in the following invoke method:

   
  1. /**
  2.     * proxy:Real proxy object of proxy class proxy com sun. proxy.$ Proxy0
  3.     * method:The Method object of the real Method of an object we want to call
  4.     * args:Refers to the parameters passed by the proxy object method
  5.     */
  6.     public Object invoke (Object proxy, Method method, Object[] args) throws Throwable;

Proxy class is a class used to create a proxy object. It provides many methods, but the most commonly used method is newProxyInstance.

   
  1. public static Object newProxyInstance (ClassLoader loader, 
  2.                                             Class<?>[] interfaces, 
  3.                                             InvocationHandler h)

The function of this method is to create a proxy class object, which receives three parameters. Let's look at the meaning of the following parameters:

  • loader: a classloader object that defines which classloader object loads the generated proxy class
  • Interfaces: an array of interface objects, which indicates what kind of interfaces we will provide to our proxy object. If we provide such an array of interface objects, then we declare that the proxy class implements these interfaces, and the proxy class can call all the methods declared in the interface.
  • h: An InvocationHandler object indicates which InvocationHandler object will be associated with when the method is called by the dynamic proxy object, and finally called by it.

6, Comparison and summary of JDK dynamic agent and CGLIB dynamic agent code examples

(1) Define and create user management interface

   
  1. /**
  2. * User management interface
  3. */
  4. public interface UserManager {
  5. //New user abstraction method
  6. void addUser (String userName, String password);
  7. //Delete user abstract method
  8. void delUser (String userName);
  9. }

(2) User management implementation class, which implements the user management interface (the implementation class of the proxy)

   
  1. /**
  2. * User management implementation class, which implements the user management interface (the implementation class of the proxy)
  3. */
  4. public class UserManagerImpl implements UserManager{
  5. //Override user add method
  6. @Override
  7. public void addUser (String userName, String password) {
  8. System.out.println( "The method added by the user has been called!");
  9. System.out.println( "Incoming parameters:\nuserName = " + userName + ", password = " + password);
  10. }
  11. //Override delete user method
  12. @Override
  13. public void delUser (String userName) {
  14. System.out.println( "Deleted method called!");
  15. System.out.println( "Incoming parameters:\nuserName = "+userName);
  16. }
  17. }

(3) JDK agent implementation: JDK dynamic agent implements InvocationHandler interface

   
  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4. /**
  5. * JDK Dynamic agent implements InvocationHandler interface
  6. */
  7. public class JdkProxy implements InvocationHandler {
  8. private Object targetObject; //Target object requiring proxy
  9. //Define the method to get the proxy object (pass in the target object for proxy)
  10. public Object getJDKProxy (Object targetObject){
  11. //Assign a value to the target object target
  12. this.targetObject = targetObject;
  13. //JDK dynamic proxy can only proxy classes that implement interfaces, as can be seen from the parameters required by the newProxyInstance function
  14. Object proxyObject = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);
  15. //Return proxy object
  16. return proxyObject;
  17. }
  18. @Override
  19. public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
  20. System.out.println( "JDK Dynamic agent, start listening!");
  21. // Call the invoke method, and result stores the return value of the method
  22. Object result = method.invoke(targetObject,args);
  23. System.out.println( "JDK Dynamic agent, listening is over!");
  24. return result;
  25. }
  26. // public static void main(String[] args) {
  27. // JdkProxy jdkProxy = new JdkProxy(); // Instantiate JDKProxy object
  28. // UserManager user = (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl()); // Get proxy object
  29. // user.addUser("admin","123456");
  30. // }
  31. }

(4) Adopt CGLIB Proxy implementation: the asm version package needs to be imported to implement the MethodInterceptor interface

   
  1. import com.proxy.UserManager;
  2. import net.sf.cglib.proxy.Enhancer;
  3. import net.sf.cglib.proxy.MethodInterceptor;
  4. import net.sf.cglib.proxy.MethodProxy;
  5. import java.lang.reflect.Method;
  6. /**
  7. * Cglib Dynamic proxy:
  8. * (You need to import two jar packages, asm-5.0.3 jar,cglib-3.1. Jar Version (optional)
  9. */
  10. //Cglib dynamic agent to implement MethodInterceptor interface
  11. public class CglibProxy implements MethodInterceptor {
  12. private Object target; //Target object requiring proxy
  13. //Override intercept method
  14. @Override
  15. public Object intercept (Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  16. System.out.println( "Cglib Dynamic agent, start listening!");
  17. Object result = method.invoke(target,args); //Method execution parameters: target object arr parameter array
  18. System.out.println( "Cglib Dynamic agent, listening is over!");
  19. return result;
  20. }
  21. //Defines the method to get the proxy object
  22. public UserManager getCglibProxy (Object targetObject) {
  23. this.target = targetObject; //Assign a value to the target object target
  24. Enhancer enhancer = new Enhancer();
  25. //Set the parent class. Because Cglib generates a subclass for the specified class, you need to specify the parent class
  26. enhancer.setSuperclass(targetObject.getClass()); //UserManagerImpl
  27. enhancer.setCallback( this); //Set callback
  28. Object result = enhancer.create(); //Create and return proxy objects
  29. return (UserManager) result;
  30. }
  31. // public static void main(String[] args) {
  32. // CglibProxy cglibProxy = new CglibProxy(); // Instantiate cglibproxy object
  33. // UserManager user = cglibProxy.getCglibProxy(new UserManagerImpl());// Get proxy object
  34. // user.delUser("admin");
  35. // }
  36. }

(5) Client call test and results

   
  1. import com.proxy.CglibProxy.CglibProxy;
  2. import com.proxy.JDKProxy.JdkProxy;
  3. public class ClientTest {
  4. public static void main (String[] args) {
  5. JdkProxy jdkProxy = new JdkProxy(); //Instantiate JDKProxy object
  6. UserManager userJdk = (UserManager) jdkProxy.getJDKProxy( new UserManagerImpl()); //Get proxy object
  7. userJdk.addUser( "admin", "123456");
  8. CglibProxy cglibProxy = new CglibProxy(); //Instantiate the CglibProxy object
  9. UserManager userCglib = cglibProxy.getCglibProxy( new UserManagerImpl()); //Get proxy object
  10. userCglib.delUser( "admin");
  11. }
  12. }

Operation results:

   
  1. JDK Dynamic agent, start listening!
  2. The method added by the user has been called!
  3. Incoming parameters:
  4. userName = admin, password = 123456
  5. JDK Dynamic agent, listening is over!
  6. Cglib Dynamic agent, start listening!
  7. Deleted method called!
  8. Incoming parameters:
  9. userName = admin
  10. Cglib Dynamic agent, listening is over!

(6) JDK and CGLIB dynamic agent summary

  • JDK dynamic agent can only generate agents for classes that implement interfaces, not for classes. It is implemented by Java reflection technology, and the process of generating classes is relatively efficient.
  • CGLIB implements a proxy for a class. It mainly generates a subclass of a specified class and covers its methods. It is implemented using the asm bytecode framework. The related execution process is more efficient. The process of generating a class can be compensated by the cache. Because it is inheritance, it is better not to declare this class or method as final
  • JDK proxy does not need the support of a third-party library. It can be used only in the JDK environment. Usage conditions: implement InvocationHandler + use proxy Newproxyinstance generates proxy object + the proxied object must implement the interface
  • CGLib must rely on CGLib's class library, but it needs classes to implement any interface proxy. It generates a subclass from the specified class and overrides the methods in it. It is an inherited proxy, but it is recommended to use JDK in the environment of interface programming;

Reference books, literature and materials

1.https://blog.csdn.net/zxzzxzzxz123/article/details/69941910

2.https://www.cnblogs.com/liubin1988/p/8909610.html

3.https://blog.csdn.net/weixin_38327420/article/details/85068641 Examples of dynamic agents

4.https://www.cnblogs.com/wangenxian/p/10885309.html

5.https://www.cnblogs.com/gonjan-blog/p/6685611.html 2. Main learning ideas and sources

OC] (write custom directory title here)

Welcome to the Markdown editor

Hello! This is the welcome page displayed by the Markdown editor for the first time. If you want to learn how to use the Markdown editor, you can read this article carefully to understand the basic grammar of Markdown.

New changes

We have expanded some functions and syntax support for the Markdown editor. In addition to the standard Markdown editor functions, we have added the following new functions to help you blog with it:

  1. The new interface design will bring a new writing experience;
  2. Set your favorite code highlight style in the creation center, and Markdown will display the selected highlight style of code slice display;
  3. The picture drag function is added. You can drag local pictures directly to the editing area for direct display;
  4. New KaTeX mathematical formula syntax;
  5. Added mermaid syntax supporting Gantt chart 1 Function;
  6. The function of multi screen editing Markdown article is added;
  7. Functions such as focus writing mode, preview mode, concise writing mode and synchronous wheel setting in left and right areas are added. The function button is located between the editing area and preview area;
  8. Added check list function.

Function shortcut

Undo: Ctrl/Command + Z
Redo: Ctrl/Command + Y
Bold: Ctrl/Command + B
Italic: Ctrl/Command + I
Title: Ctrl/Command + Shift + H
Unordered list: Ctrl/Command + Shift + U
Ordered list: Ctrl/Command + Shift + O
Checklist: Ctrl/Command + Shift + C
Insert code: Ctrl/Command + Shift + K
Insert link: Ctrl/Command + Shift + L
Insert picture: Ctrl/Command + Shift + G
Find: Ctrl/Command + F
Replace: Ctrl/Command + G

Creating a reasonable title is helpful to the generation of the directory

Directly input once #, and press space to generate level 1 title.
After entering twice #, and pressing space, a level 2 title will be generated.
By analogy, we support level 6 titles. It helps to generate a perfect directory after using TOC syntax.

How to change the style of text

Emphasize text emphasize text

Bold text bold text

Tag text

Delete text

Reference text

H2O is a liquid.

210 the result is 1024

Insert links and pictures

Link: link.

Picture:

Pictures with dimensions:

Centered picture:

Centered and sized picture:

Of course, in order to make users more convenient, we have added the image drag function.

How to insert a beautiful piece of code

go Blog settings Page, select a code slice highlighting style you like, and the same highlighted code slice is shown below

// An highlighted block
var foo = 'bar';

Generate a list that suits you

  • project
    • project
      • project
  1. Item 1
  2. Item 2
  3. Item 3
  • Planning tasks
  • Complete the task

Create a table

A simple table is created as follows:

projectValue
computer$1600
mobile phone$12
catheter$1

The setting content is centered, left and right

Use: ---------: Center
Use: --------- left
Usage -----------: right

First columnSecond columnThird column
First column text centeredThe text in the second column is on the rightThe text in the third column is left

SmartyPants

SmartyPants converts ASCII punctuation characters to "smart" printed punctuation HTML entities. For example:

TYPEASCIIHTML
Single backticks'Isn't this fun?''Isn't this fun?'
Quotes"Isn't this fun?""Isn't this fun?"
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

Create a custom list

Markdown Text-to- HTML conversion tool Authors John Luke

How to create a footnote

A text with footnotes. 2

Annotations are also essential

Markdown converts text to HTML.

KaTeX mathematical formula

You can render LaTeX mathematical expressions using KaTeX:

Gamma formula display Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ (n)=(n−1)! ∀ N ∈ N is through Euler integral

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞​tz−1e−tdt.

You can find more information about LaTeX mathematical expressions here.

New Gantt chart features to enrich your articles

  • For Gantt chart syntax, refer to here,

UML diagram

UML diagrams can be used for rendering. Mermaid For example, a sequence diagram is generated as follows:

This will produce a flowchart.:

  • For Mermaid syntax, see here,

FLowchart

We will still support the flowchart of flowchart:

  • For Flowchart syntax, refer to here.

Export and import

export

If you want to try this editor, you can edit it at will in this article. When you have finished writing an article, find the article export in the upper toolbar and generate one md file or html file for local saving.

Import

If you want to load an article you wrote md file. In the upper toolbar, you can select the import function to import the file with the corresponding extension,
Continue your creation.

  1. mermaid syntax description ↩︎

  2. Explanation of footnotes ↩︎

Keywords: Java Design Pattern AOP SSM

Added by theex on Fri, 21 Jan 2022 07:24:46 +0200