(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!