Static proxy
Static agent role analysis
-
Abstract role: it is generally implemented using interfaces or abstract classes
-
Real role: the role represented
-
Acting role: acting for the real role; After representing a real role, you usually do some ancillary operations
-
Customer: use the agent role to perform some operations
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(); } }
Analysis: in this process, what you directly contact is the intermediary. Just like in real life, you can't see the landlord, but you still 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.
Benefits of static agents:
-
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:
-
With more classes and more proxy classes, the workload becomes larger Reduced development efficiency
We want the benefits of static agent, but we don't want the disadvantages of static agent, so we have dynamic agent!
Static agent re understanding
After the students have finished their practice, let's give another example to consolidate everyone's learning!
Practice steps:
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. 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 the agent class to realize the log function! proxy.setUserService(userService); proxy.add(); } }
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 are divided into two categories: one is interface based dynamic agents, and the other is class based dynamic agents
-
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
The dynamic proxy of JDK needs to know two classes
[InvocationHandler: call handler]
Object # invoke(Object # proxy, method # method, object [] args);
//Parameters
//Proxy - the proxy instance that calls the method
//Method - the method corresponds to the instance that invokes 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 the proxy instance, 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]
//Generate proxy class public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); }
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 call 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(); pih.setRent(host); //Put the real character in! Rent proxy = (Rent)pih.getProxy(); //Dynamically generate the corresponding proxy class! 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!
Deepen understanding
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!
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 call 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 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); //Sets the object to proxy UserService proxy = (UserService)pih.getProxy(); //Dynamically generate proxy class! proxy.delete(); } }
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, generally acting for a certain kind of business
-
A dynamic proxy can proxy multiple classes, and the proxy is the interface!