6. Spring Static and Dynamic Agent Modes

Posted by jacomus on Tue, 08 Feb 2022 18:50:27 +0100

(The article notes come from the b-station video, meets the mad saying, carries the notes as learning, for your reference to study together)

Static/dynamic proxy mode

proxy pattern

Why learn proxy mode, because the underlying mechanism of AOP is dynamic proxy!

Agent mode:

  • Static Proxy
  • Dynamic Proxy

Before learning aop, learn about proxy mode!

Static Proxy

Static Proxy Role Analysis

  • Abstract roles: typically implemented using interfaces or abstract classes

  • Real Role: The Role to be Agented

  • Agent role: Actual role of agent; After the agent has a real role, it usually does some subsidiary operations.

  • Customer: Use the proxy role for some operations.

code implementation

Rent. Java is an abstract role

//Abstract Role: Rental
public interface Rent {
   public void rent();
}

Host. Java is the real character

//Real role: landlord, landowner wants to rent a house
public class Host implements Rent{
   public void rent() {
       System.out.println("House Rental");
  }
}

Proxy. Java is the proxy role

//Agent role: intermediary
public class Proxy implements Rent {

   private Host host;
   public Proxy() { }
   public Proxy(Host host) {
       this.host = host;
  }

   //Rental
   public void rent(){
       seeHouse();
       host.rent();
       fare();
  }
   //Housekeeping
   public void seeHouse(){
       System.out.println("Take tenants to the room");
  }
   //Collecting intermediary fees
   public void fare(){
       System.out.println("Collecting intermediary fees");
  }
}

Client. Java is customer

//Customer class, general customers will go to find agents!
public class Client {
   public static void main(String[] args) {
       //Landlord wants to rent
       Host host = new Host();
       //Intermediaries help landlords
       Proxy proxy = new Proxy(host);

       //You go to an intermediary!
       proxy.rent();
  }
}

Analysis: In this process, you directly contact the intermediary, just like in real life, you can not see the landlord, but you still rent the landlord's house through the agent, which is the so-called agent mode, the program originates from life, so people who learn programming can generally view things in life more abstractly.

Benefits of static proxy:

  • Can make our real roles more pure. Don't focus on something public anymore.
  • Public business is done by agents. A division of business has been achieved.
  • More centralized and convenient when public business expands.

Disadvantages:

  • More classes, more proxy classes, more workload. Development efficiency is reduced.

We want the benefits of a static proxy, but we don't want the drawbacks of a static proxy, so we have a dynamic proxy!

Static proxy Reinterpretation

Practice steps:

1. To create an abstract role, such as the user business that we usually do, is to add, delete, and check in the abstraction!

//Abstract Role: Add, delete, change check business
public interface UserService {
   void add();
   void delete();
   void update();
   void query();
}

2. We need a real object to complete these additions and deletions

//Real object, the person who completes the add-delete check
public class UserServiceImpl implements UserService {

   public void add() {
       System.out.println("Add a user");
  }

   public void delete() {
       System.out.println("Deleted a user");
  }

   public void update() {
       System.out.println("Updated a user");
  }

   public void query() {
       System.out.println("Queried a user");
  }
}

3. The demand has come, now we need to add a log function, how to achieve it!

  • Idea 1: Add code to the implementation class [Trouble!]
  • Idea 2: It is best to use an agent to achieve this function without changing the original business situation!

4. Set up a proxy class to process the log! delegable role

//Agent role, where log implementation is added
public class UserServiceProxy implements UserService {
   private UserServiceImpl userService;

   public void setUserService(UserServiceImpl userService) {
       this.userService = userService;
  }

   public void add() {
       log("add");
       userService.add();
  }

   public void delete() {
       log("delete");
       userService.delete();
  }

   public void update() {
       log("update");
       userService.update();
  }

   public void query() {
       log("query");
       userService.query();
  }

   public void log(String msg){
       System.out.println("Executed"+msg+"Method");
  }

} 

5. Test Access Class:

public class Client {
   public static void main(String[] args) {
       //Real Business
       UserServiceImpl userService = new UserServiceImpl();
       //proxy class
       UserServiceProxy proxy = new UserServiceProxy();
       //Use proxy class for logging!
       proxy.setUserService(userService);

       proxy.add();
  }
}

We have enhanced the original function without changing the original code, which is the core idea in AOP

Talk about AOP: vertical development, horizontal development

Dynamic Proxy

  • Dynamic agents have the same roles as static agents.

  • Dynamic proxy proxy classes are dynamically generated. The proxy class of the static proxy was written in advance

  • Dynamic proxies are divided into two categories: one is interface-based dynamic proxy and the other is class-based dynamic proxy.

    • Interface-based Dynamic Proxy--JDK Dynamic Proxy
    • Class-based dynamic proxy - cglib
    • More javasist is now used to generate dynamic proxies. Baidu a bit javasist
    • We use JDK's native code here, and the rest is the same!,

The dynamic proxy for JDK requires understanding two classes

Core: InvocationHandler and Proxy, open JDK Help Document and see

[InvocationHandler: Call Handler]

Object invoke(Object proxy, Method method, Object[] args);
//parameter
//Proxy - proxy instance calling this method
//Method - The method described corresponds to an instance calling an interface method on a proxy instance. The declaring class of the method object will be the interface declared by the method, which can be a superinterface of the proxy interface whose proxy class inherits the method.
//args - Contains an array of methods that call objects that pass parameter values for proxy instances, or null if interface methods have no parameters. Parameters of the original type are included in the appropriate instance of the original wrapper class, such as java.lang.Integer or java.lang.Boolean.

[Proxy: Proxy]

//Generate Proxy Class
public Object getProxy(){
   return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                                 rent.getClass().getInterfaces(),this);
}

code implementation

Abstract and real roles are the same as before!

Rent. Java is an abstract role

//Abstract Role: Rental
public interface Rent {
   public void rent();
}

Host. Java is the real character

//Real role: landlord, landowner wants to rent a house
public class Host implements Rent{
   public void rent() {
       System.out.println("House Rental");
  }
}

ProxyInvocationHandler. java is the proxy role

public class ProxyInvocationHandler implements InvocationHandler {
   private Rent rent;

   public void setRent(Rent rent) {
       this.rent = rent;
  }

   //Generate proxy classes, focusing on the second parameter, to get Abstract roles to proxy! Once a role, you can now proxy a class of roles
   public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               rent.getClass().getInterfaces(),this);
  }

   // Proxy: method of proxy class: method object of proxy class calling handler.
   // Processing method calls on proxy instances and returning results
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       seeHouse();
       //Core: Essentially using reflection!
       Object result = method.invoke(rent, args);
       fare();
       return result;
  }

   //Housekeeping
   public void seeHouse(){
       System.out.println("Take tenants to the room");
  }
   //Collecting intermediary fees
   public void fare(){
       System.out.println("Collecting intermediary fees");
  }

}

Client . java

//Tenant
public class Client {

   public static void main(String[] args) {
       //Real Role
       Host host = new Host();
       //Call handler for proxy instance
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setRent(host); //Put real characters in!
       Rent proxy = (Rent)pih.getProxy(); //Dynamically generate the corresponding proxy class!
       proxy.rent();
  }

}

Core: a dynamic proxy, generally proxy a certain type of business, a dynamic proxy can proxy multiple classes, proxy is the interface!,

Deepen understanding

Let's use a dynamic proxy to implement the UserService we wrote later!

We can also write a generic dynamic proxy implementation class! All proxy objects can be set to Object!

public class ProxyInvocationHandler implements InvocationHandler {
   private Object target;

   public void setTarget(Object target) {
       this.target = target;
  }

   //Generate Proxy Class
   public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               target.getClass().getInterfaces(),this);
  }

   // Proxy: proxy class
   // Method: The method object of the proxy class's call handler.
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       log(method.getName());
       Object result = method.invoke(target, args);
       return result;
  }

   public void log(String methodName){
       System.out.println("Executed"+methodName+"Method");
  }

}

Test!

public class Test {
   public static void main(String[] args) {
       //Real object
       UserServiceImpl userService = new UserServiceImpl();
       //Call handler for proxy object
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setTarget(userService); //Set Objects to Proxy
       UserService proxy = (UserService)pih.getProxy(); //Dynamically generate proxy classes!
       proxy.delete();
  }
}

Test, add, delete, check, see the results!

Benefits of dynamic proxy

It has all static agents, and it has none!

  • Can make our real roles more pure. Don't focus on something public anymore.
  • Public business is done by agents. A division of business has been achieved.
  • More centralized and convenient when public business expands.
  • A dynamic agent that generally acts as an agent for a certain type of business
  • A dynamic proxy can proxy multiple classes, but it proxyes interfaces!

Topics: Java Programming Spring Design Pattern