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)