Static / dynamic proxy mode
Why learn the agent mode? Because the underlying mechanism of AOP is dynamic agent!
Agent mode is divided into static agent and dynamic agent
Before learning aop, we should first understand the agent mode!
1. Static agent
1.1 static agent project structure
1.2 taking renting as an example, static agent role analysis
Abstract role: it is usually solved by using interfaces or abstract classes
Real role: the role represented
Agent role: represent the real role. After representing the real role, we usually do some ancillary operations
Client: the person who accesses the proxy object!
1.3 code implementation
Rent . java is an abstract role
//Abstract role: renting a house public interface Rent { public void rent(); }
Host . java is the real role
//Real role: landlord, the landlord wants to rent the 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; } //Rent a house public void rent(){ seeHouse(); host.rent(); fare(); } //House viewing public void seeHouse(){ System.out.println("Show the tenant"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
Client . java is the customer
//Customers, general customers will find agents! public class Client { public static void main(String[] args) { //The landlord wants to rent a house Host host = new Host(); //The intermediary helps the landlord Proxy proxy = new Proxy(host); //You go to the agency! proxy.rent(); } }
1.4 in the client Java test run
1.5 analysis
In this process, you are in direct contact with the intermediary, just like in real life. You can't see the landlord, but you rent the landlord's house through the agent. This is the so-called agent model. The program comes from life, so people who learn programming can generally look at what happens in life in a more abstract way.
1.6 advantages and disadvantages of static agent
advantage:
- It can make our real role more pure Stop paying attention to some public things
- Public business is done by agents Realized the division of business,
- When the public business expands, it becomes more centralized and convenient
Disadvantages: more classes, more agent classes, larger workload and lower development efficiency
We want the benefits of static agent, but we don't want the disadvantages of static agent, so we have dynamic agent!
2. Re understanding of static agent
After the students have finished their practice, let's give another example to consolidate everyone's learning!
2.1 static agent re understanding project structure
2.2 code implementation
1. Create an abstract role, such as the user business we usually do, which is abstracted to add, delete, modify and check!
//Abstract role: add, delete, modify and query business public interface UserService { void add(); void delete(); void update(); void query(); }
2. We need a real object to complete these operations
//Real object, the person who completes the operation of addition, deletion, modification and query public class UserServiceImpl implements UserService { public void add() { System.out.println("Added a user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("Updated a user"); } public void query() { System.out.println("Queried a user"); } }
3. The demand is coming. Now we need to add a log function. How to implement it!
- Idea 1: add code on the implementation class [trouble!]
- Idea 2: using an agent to do it, it is the best to realize this function without changing the original business!
4. Set up a proxy class to handle logs! delegable role
//Agent role, in which the implementation of log 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("Yes"+msg+"method"); } }
5. Access class: Client
public class Client { public static void main(String[] args) { //Real business UserServiceImpl userService = new UserServiceImpl(); //proxy class UserServiceProxy proxy = new UserServiceProxy(); //Use the agent class to realize the log function! proxy.setUserService(userService); proxy.add(); } }
6. In the client Run on Java
OK, by now, there should be no problem with the agency mode. The key point is that you need to understand the idea;
We have enhanced the original functions without changing the original code, which is the core idea of AOP
Understanding of vertical development and horizontal development
3. Dynamic agent
The role of dynamic agent is the same as that of static agent
The proxy class of dynamic proxy is generated dynamically The proxy class of static proxy is written in advance
Dynamic agents fall into two categories:
Dynamic agent based on interface -- JDK dynamic agent
Class based dynamic proxy -- cglib
Javasist is often used to generate dynamic proxy Baidu javasist
We use the native code of JDK here, and the rest is the same!
3.1 the dynamic agent of JDK needs to understand two classes
Core: InvocationHandler and Proxy. Open the JDK help document and have a look
① [InvocationHandler: call handler]
public interface InvocationHandler
InvocationHandler is an interface implemented by the calling handler of the proxy instance.
Each proxy instance has an associated invocation handler. When a method is called on a proxy instance, the method call is encoded and dispatched to the invoke method of its call handler.
//Process method calls on code instances and return results Object invoke(Object proxy, method method, Object[] args);
parameter
Proxy: the proxy instance that calls the method
Method: the method corresponds to the instance calling the interface method on the proxy instance. The declared class of the method object will be the interface declared by the method, which can be the super interface of the proxy interface of the proxy class inheriting the method.
args: array of objects containing method calls that pass the parameter values of proxy instances, or null if the interface method has no parameters. The parameters of the primitive type are contained in an instance of the appropriate primitive wrapper class, such as Java Lang. integer or Java lang.Boolean .
② [Proxy: Proxy]
public class Proxy extends object implements Serializable
Proxy provides static methods for creating dynamic proxy classes and instances. It is also a superclass of all dynamic proxy classes created by these methods.
Dynamic proxy class (hereinafter referred to as proxy class) is a class that implements the interface list specified at runtime when the class is created, and has the following behaviors. A proxy interface is an interface implemented by a proxy class. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object that implements the interface InvocationHandler. The method call on the proxy instance through one of its proxy interfaces will be dispatched to the invoke method of the instance call handler to pass the proxy instance, Java Iang. reflect. Method the Java. Method of the called method lang.reflect. Method object and an array of type object Object containing parameters. The call handler handles the encoded method call appropriately, and the returned result will be returned as the result of the method called on the proxy instance.
//Generate proxy class public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); }
3.2 dynamic agent project structure
3.3 code implementation
Abstract characters and real characters are the same as before!
Rent . java is an abstract role
//Abstract role: renting a house public interface Rent { public void rent(); }
Host . java is the real role
//Real role: landlord, the landlord wants to rent the 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 class, focusing on the second parameter to obtain the abstract role to be proxy! It used to be a role, but now it can represent a kind of role public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); } // Proxy: proxy class method: the method object of the calling handler of the proxy class // Process method calls on proxy instances and return results @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //Core: essence is realized by reflection! Object result = method.invoke(rent, args); fare(); return result; } //House viewing public void seeHouse(){ System.out.println("Show the tenant"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
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(); //Put the real character in! pih.setRent((host); //Dynamically generate the corresponding proxy class! Rent proxy = (Rent)pih.getProxy(); proxy.rent(); } }
Core: a dynamic agent generally represents a certain type of business. A dynamic agent can represent multiple classes, and the agent is the interface!
4. Deepen understanding
4.1 deepen understanding of project structure
4.2 code implementation
Let's use dynamic proxy to implement UserService written later!
We can also write a general dynamic proxy implementation class! All proxy objects can be set to Object!
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; 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 calling handler of the proxy class 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("Yes"+methodName+"method"); } }
Test!
public class Client { public static void main(String[] args) { //Real object UserServiceImpl userService = new UserServiceImpl(); //Call handler for proxy object ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService); //Sets the object to proxy UserService proxy = (UserService)pih.getProxy(); //Dynamically generate proxy class! proxy.delete(); } }
Test, add, delete, modify and check the results!
Benefits of dynamic agents
It has all the static agents. It also has all the static agents that don't have!
- It can make our real role more pure Stop paying attention to some public things
- Public business is done by agents Realized the division of business,
- When the public business expands, it becomes more centralized and convenient
- A dynamic agent is an interface, which is generally a corresponding type of business
- A dynamic proxy can proxy multiple classes as long as it implements the same interface