Proxy model of Spring basic learning

Posted by eazyGen on Fri, 15 Oct 2021 19:38:58 +0200

preface:

Hello, guys, I'm running snail rz. Of course, you can call me snail Jun. I'm a rookie who has studied Java for more than half a year. At the same time, I also have a great dream, that is, to become an excellent Java Architect one day.
This Spring basic learning series is used to record the whole process of learning the basic knowledge of Spring framework (this series is written with reference to the latest Spring 5 tutorial of crazy God in station B. because it was sorted out before, but it was not released at that time, there may be errors in some places. I hope you can correct them in time!)
After that, I will update this series at a faster rate day by day. If you haven't learned the spring 5 framework, you can learn from my blog; Of course, the little friends who have studied can also review the basics with me.
Finally, I hope I can make progress with you! Come on! Boys!
No more nonsense. Let's start today's learning content. Today we come to the ninth stop of Spring basic learning: proxy mode!

10. Agency mode

Why learn agent mode?

Because this is the underlying implementation principle of Spring AOP, we need to understand it

Agent mode is divided into several types?

  • Static proxy
  • Dynamic agent

10.1 static agent

10.1.1 role analysis

  • Abstract role: it is generally implemented using interfaces or abstract classes (for example, abstracting the rental business into an interface)
  • Real role: the role of the agent (e.g. the landlord who rents a house)
  • Acting role: acting as an agent for real roles (such as an intermediary who helps the landlord rent a house). After acting as an agent for real roles, you will generally do some ancillary operations (such as showing customers a house, signing a contract, collecting intermediary fees, etc.)
  • Client: the person who accesses the proxy object (the customer who comes to rent a house)

10.1.2 implementation of rental case with static agent

1. Prepare the rental interface

// Define (Abstract role) rental interface
public interface Rent {
    
    // rent() method
    public void rent();
}

2. Write the real role

// Landlord entity class that implements the rental interface (real role)
public class Host implements Rent {
    
    // Override rent() method
    public void rent() {
        System.out.println("The landlord wants to rent the house!");
    }
}

3. Write agent role mediation

// Create a proxy role (mediation) that implements the rental interface
public class Proxy implements Rent {
    
    private Host host;
    
    // Parameterless constructor
    public Proxy() {

    }
    
    // Parametric construction method
    public Proxy(Host host) {
        this.host = host;
    }
    
    // Override rent() method
    public void rent() {
        host.rent(); // rent an apartment
        seeHouse(); // Look at the house
        contract(); // sign a contract
        fare(); // Intermediary fee
    }
    
    // Look at the rental room
    public void seeHouse() {
        System.out.println("The agent will show you the house");
    }
    
    // sign a contract
    public void contract() {
        System.out.println("Sign lease contract");
    }
    
    // Intermediary fee
    public void fare() {
        System.out.println("Collect intermediary fees from the landlord");
    }
    
}

4. Client access agent role

// Customer entity class
public class Client {
    public static void main(String[] args) {
        
        // The landlord wants to rent a house
        Host host = new Host();
        // Acting: the agent helps the landlord rent a house, but the agent role usually has some ancillary operations
        Proxy proxy = new Proxy(host);
        // Customers don't have to face the landlord, just find an intermediary to rent a house
        proxy.rent();
    }
    
}

5. Test results

10.1.3 advantages and disadvantages of static agent

1. Benefits

  • It can make the operation of the real role more pure without paying attention to some public affairs (for example, the real role landlord only needs to rent a house)
  • Public affairs are handled by the agent role, which realizes the division of business and reduces the coupling (public affairs such as house viewing and contract signing are handled by the agent role intermediary)
  • When the public business is expanded, it is convenient for centralized management (for example, if the landlord has a new business to expand, such as collecting water and electricity charges, it can also be handled by the agent role intermediary without adding its own business quantity)

2. Disadvantages

  • A real role means that a proxy role will be generated, so the amount of code will double and the development efficiency will be low

10.1.4 deepening understanding of static agents

1. Write abstract roles

// Create user service interface (Abstract role)
public interface UserService {
    
    // Define addition, deletion, modification and query methods
    
    public void add();
    
    public void delete();
    
    public void update();
    
    public void query();
    
}

2. Write real roles

// Implementation class of user service interface (real role)
public class UserServiceImpl implements UserService {
    
    // OOP has seven principles, which comply with the opening and closing principles: that is, software entities are open to expansion and closed to modification
    
    public void add() {
        System.out.println("Add a user");
    }
    
    public void delete() {
        System.out.println("Delete a user");
    }
    
    public void update() {
        System.out.println("Modify and add a user");
    }
    
    public void query() {
        System.out.println("Query a user");
    }
    
    // Changing the original business code is a big taboo in the company
    
}

3. Write agent roles

// A proxy role that implements the user service interface
public class UserServiceProxy implements UserService {
    
    // Introducing real characters
    private UserServiceImpl userService;
    
    // Set user service method
    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
    
    /**
     * Addition, deletion, modification and query method of rewriting user service interface
     */
    public void add() {
        // Call log() method
        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();
    }
    
    //Log method
    public void log(String msg) {
        System.out.println("Used"+msg+"method");
    }
}

4. Simulate client access agent role

public class Client {
    public static void main(String[] args) {
        
        // Instantiate real characters
       UserServiceImpl userService = new UserServiceImpl();
        // Instantiate proxy role
       UserServiceProxy proxy = new UserServiceProxy();
       // The agent role acts as an agent for business, but there will also be other ancillary operations
       proxy.setUserService(userService);
        // The client directly accesses the proxy role without facing the real role
        proxy.query();
    }
    
}

5. Test results

6. Talk about AOP

10.2 dynamic agent

10.2.1 preliminary understanding of dynamic agent

1. Dynamic agent characteristics

  • Dynamic proxy has the same role as static proxy (i.e. real role, abstract role, proxy role and client)

  • The proxy class of dynamic proxy is generated dynamically, not written directly in advance

  • Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents

    1. Interface based: JDK dynamic agent

2. Class based: cglib

3. java bytecode implementation: javassist

2. Interface based dynamic agent

Before implementing JDK dynamic proxy, we need to understand two classes:

One is Proxy and the other is InvocationHandler

  • InvocationHandler: an interface implemented by the proxy object instance to call the handler
  • Proxy: it is a static method that provides the creation of dynamic proxy classes and instances

10.2.2 cases of dynamic agent realizing rental

1. Write abstract roles

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

2. Write real roles

// Real role landlord: in fact, it realizes the rental interface
public class Host implements Rent {
    
    // Override rent() method
    public void rent() {
        System.out.println("The landlord wants to rent the house!");
    }
    
}

3. Write a dynamic agent tool class

// This class can automatically generate a proxy class, which is equivalent to that used by the mediation (because it cannot directly proxy, but is responsible for providing mediation)
public class ProxyInvocationHandler implements InvocationHandler {
    
    // Proxy rental interface class
    private  Rent rent;
    
    // Dynamic value injection using set method
    public void setRent(Rent rent) {
        this.rent = rent;
    }
    
    // Generated proxy class
    public Object getProxy() {
        // The return value is to call the newProxyInstance method of the proxy class to obtain the proxy role instance
        // There are three parameters: the first parameter is the class loader of the current class, and the second parameter is the interface of the implementation class that creates the instance
        // The third parameter is InvocationHandler calling the handler interface
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(),this);
    }
    
    // To process proxy instances and enhance them, you need to return results
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // The essence of dynamic agent is to use reflection mechanism
        // Front enhancement: look at the house
        seeHouse();
        // Method of target class
        Object result = method.invoke(rent,args);
        // Post enhancement: collect intermediary fee
        fare();
        // Return result object
        return result;
    }
    
    // Front enhancement method: look at the house
    public void seeHouse() {
        System.out.println("The intermediary showed the customer the house");
    }
    
    // Post enhancement method: collect intermediary fee
    public void fare() {
        System.out.println("Intermediary fee");
    }
    
}

4. Simulate client access agent role

// Client access agent role
public class Client {
    public static void main(String[] args) {
        
        // Get real role landlord
        Host host = new Host();
        // Get the dynamic agent tool class (mediation): at present, the agent role mediation has not appeared
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        // Set the proxy object: inject the proxy object host by calling the setRent method of the dynamic proxy tool class (intermediary)
        pih.setRent(host);
        // Dynamically generate proxy role class proxy (mediation): the proxy role mediation only appears at this time
        Rent proxy = (Rent) pih.getProxy();
        // When calling the rent method of the proxy class, the invoke method will be called through the reflection mechanism to achieve method enhancement
        // The client directly accesses the intermediary to rent a house
        proxy.rent();
        
    }
}

5. Test results

10.2.3 benefits of dynamic agents

  • It can make the operation of the real role more pure without paying attention to some public affairs (the real role landlord only needs to pay attention to the rental business)
  • Public affairs are handed over to the agent role, which realizes the division of business and reduces the coupling (public affairs such as looking at houses and signing contracts are handled by the agent role intermediary)
  • When the public business is expanded, it is convenient for centralized management (if the landlord wants to expand new business, such as collecting water and electricity charges, it can be handed over to the agent role intermediary without adding its own business)
  • A dynamic agent class represents an interface, which is generally a corresponding type of business
  • A dynamic proxy class can proxy multiple classes as long as it implements the same interface

10.2.4 dynamic proxy (single real object)

1. Write abstract roles

// Create user service interface (Abstract role)
public interface UserService {
    
    // Define addition, deletion, modification and query methods
    public void add();
    
    public void delete();
    
    public void update();
    
    public void query();
    
}

2. Write real roles

// Implementation class of user service interface (real role)
public class UserServiceImpl implements UserService {
    
    // Method of rewriting addition, deletion, modification and query
    public void add() {
        System.out.println("Add a user");
    }
    
    public void delete() {
        System.out.println("Delete a user");
    }
    
    public void update() {
        System.out.println("Modify and add a user");
    }
    
    public void query() {
        System.out.println("Query a user");
    }
    
}

3. Dynamic agent tool class

// ProxyInvocationHandler is used to generate a dynamic proxy instance, which is equivalent to that used by the mediation
// InvocationHandler calls the handler and returns the result
public class ProxyInvocationHandler implements InvocationHandler {
    
    //Proxy interface class
    private  Object target;
    
    // Dynamic value injection using set method
    public void setTarget(Object target) {
        this.target = target;
    }
    
    // Generated proxy class
    public Object getProxy() {
        // The return value is the Proxy object instance: obtained by the Proxy object Proxy calling the newProxyInstance method
        // There are three parameters: the first is the class loader of the current class, and the second is the interface of the implementation class that creates the instance
        // The third is InvocationHandler calling the handler interface
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }
    
    // Process the proxy instance, enhance the method, and return the result
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // The essence of dynamic agent is to use reflection mechanism
        // Pre enhancement: log method
        log(method.getName());
        // Method of target class
        Object result = method.invoke(target,args);
        // Return result object
        return result;
    }
    
    // Log method
    public void log(String msg) {
        System.out.println("Yes"+msg+"method");
    }
    
}

4. Simulate client access proxy object

// Client role: renter
public class Client {
    public static void main(String[] args) {
        
        // Get real characters
        UserServiceImpl userService = new UserServiceImpl();
        // Get the dynamic agent tool class (mediation): at present, the agent role (mediation) has not been generated
        ProxyInvocationHandler pih= new ProxyInvocationHandler();
        // Sets the object to proxy
        pih.setTarget(userService);
        // Dynamically generate proxy class instances: the proxy role mediation only appears at this time
        UserService proxy = (UserService) pih.getProxy();
        // When calling the method of proxy class, the invoke method is automatically called through the reflection mechanism to realize method enhancement
        // Agent class instance executes business
        proxy.add();
        
    }
}

5. Test results

10.2.5 dynamic proxy (multiple real objects)

1. Write abstract roles

  • Abstract role interface with 10.2.4

2. Write real roles

  • On the basis of a real role in 10.2.4, add a real role UserServiceImpl2
// Implementation class of user service interface (second real role)
public class UserServiceImpl2 implements UserService {
    
    // Rewrite addition, deletion, modification and query methods
    public void add() {
        System.out.println("Add a user information");
    }
    
    public void delete() {
        System.out.println("Delete a user information");
    }
    
    public void update() {
        System.out.println("Modify and add a user information");
    }
    
    public void query() {
        System.out.println("Query a user information");
    }
    
}

3. Write a dynamic agent tool class

  • The same as 10.2.4 dynamic agent tool class

4. Simulate client access agent role

public class Client {
    public static void main(String[] args) {
        // Get multiple real characters
        UserServiceImpl userService = new UserServiceImpl();
        UserServiceImpl2 userService2 = new UserServiceImpl2();
        // Get the dynamic proxy tool class (used by the mediation): at this time, the proxy role mediation has not yet appeared
        ProxyInvocationHandler pih= new ProxyInvocationHandler();
        ProxyInvocationHandler pih2= new ProxyInvocationHandler();
        // Set multiple objects to proxy: implement proxy role injection by calling setTarget method of dynamic proxy tool class
        pih.setTarget(userService);
        pih2.setTarget(userService2);
        // Dynamically generate multiple proxy classes: the proxy role mediation appears only at this time
        UserService proxy = (UserService) pih.getProxy();
        UserService proxy2 = (UserService) pih2.getProxy();
        // Multiple proxy class instances execute business as agents
        proxy.add();
        proxy2.delete();
    }
}

5. Test results

Well, this is the end of today's study on agency mode. Welcome to study and discuss actively. If you like, you can pay attention to Mr. snail. By the way, let's have a one button three times. See you next time. Bye!

Reference video link: https://www.bilibili.com/video/BV1WE411d7Dv([crazy God says Java] the latest tutorial of spring 5, the IDEA version is easy to understand)

Topics: AOP Dynamic Proxy