This article will explain the agent mode through its concept, characteristics, and finally realize the use scenarios of each agent mode through coding.
What is agent mode
Agent pattern is a programming design pattern in Java language. There are two important roles: the principal class and the agent class. The agent class can call the delegate class and extend the existing functions of the delegate class.
How to understand this model? The common things in daily life are as follows:
The landlord gives the house he needs to rent to the real estate agent to help him manage the complicated process including taking the tenant to see the house, signing the contract, etc. the landlord only needs to obtain benefits through the house at last. In this case, the landlord is the principal and the real estate intermediary is the agent.
In Java development, agents are divided into static agents and dynamic agents.
Dynamic agents are divided into jdk dynamic agents and cglib dynamic agents.
Characteristics of static agent and dynamic agent
Static agent
Advantage: it can add new functions through proxy class without modifying the code of delegate class.
Disadvantages: both the delegate class and the proxy class implement the interface of the parent class. Once the interface code of the parent class changes, both the delegate class and the proxy class need to maintain the code.
Dynamic agent
The jdk agent in dynamic agent can solve that shortcoming in static agent. The proxy class of jdk dynamic proxy does not need to implement the parent interface, but the delegate class needs to implement the parent interface.
It not only simplifies the programming work, but also improves the scalability of the software system.
The above static agent and jdk dynamic agent must let the delegate class implement the parent interface. If the delegate class does not implement any interface, the two agent modes will not work, so the cglib dynamic agent will be on top.
Code to implement static agent
Interface of parent class
/** * Interface of parent class * @author Yang 33 * @date 2020/6/18 19:48 */ public interface ParentInterface { /** * Ways to make money */ void money(); }
Entrustment: Landlord
/** * Client: Landlord * @author Yang 33 * @date 2020/6/18 19:20 */ public class Owner implements ParentInterface { /** * How landlords make money */ public void money() { System.out.println("Landlord: it's comfortable to lie down and earn money..."); } }
Agent class: mediation
/** * Agent class: mediation * @author Yang 33 * @date 2020/6/18 19:45 */ public class Medium implements ParentInterface { //Introduce the landlord object and connect with the intermediary private Owner owner; public Medium(Owner owner) { this.owner = owner; } /** * The agent class extends the existing functions of the agent class */ public void money() { System.out.println("Intermediary: lead clients to look around..."); System.out.println("Agent: sit down and negotiate with the client to sign the rental contract..."); //Tell the landlord it's money owner.money(); } }
Test method:
/** * @author Yang 33 * @date 2020/6/18 19:54 */ public class Demo { public static void main(String[] args) { //Delegation class Owner owner = new Owner(); //proxy class Medium medium = new Medium(owner); medium.money(); } }
Print results of running test method:
Intermediary: leading customers around to see the house Agent: sit down and sign a rental contract with the client Landlord: it's comfortable to lie down and earn money
Coding for jdk dynamic proxy
The jdk dynamic Proxy must be used in the Java API, java.lang.reflect The Proxy class and InvocationHandler interface in the package.
Modify the agent class in the above static agent as follows:
import java.lang.reflect.Proxy; /** * Agent class: mediation * @author Yang 33 * @date 2020/6/18 19:45 */ public class Medium { //Introduce delegate class and associate with proxy class private Object object; public Medium(Object object) { this.object = object; } /** * The agent class extends the existing functions of the agent class */ public Object getProxyInstance() { return Proxy.newProxyInstance( object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Intermediary: lead clients to look around..."); System.out.println("Agent: sit down and negotiate with the client to sign the rental contract..."); //Tell the landlord it's money Object invoke = method.invoke(object, args); return invoke; } } ); } }
Test method:
/** * @author Yang 33 * @date 2020/6/18 19:54 */ public class Demo { public static void main(String[] args) { //Delegation class ParentInterface owner = new Owner(); //proxy class ParentInterface proxyInstance = (ParentInterface)new Medium(owner).getProxyInstance(); proxyInstance.money(); } }
Print results of running test method:
Agent: lead clients to look around Agent: sit down and sign a rental contract with the client Landlord: it's comfortable to lie down and earn money
Implementation of cglib dynamic proxy by coding
Using cglib dynamic agent, we need to introduce dependency into maven project
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
Delegate class, does not implement any interface
/** * Entrustment: Landlord * @author Yang 33 * @date 2020/6/18 19:20 */ public class Owner { /** * How landlords make money */ public void money() { System.out.println("Landlord: it's comfortable to lie down and earn money..."); } }
Proxy class:
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * cglib Proxy subclass of * @author Yang 33 * @date 2020/6/18 19:45 */ public class Medium implements MethodInterceptor { //Introduce delegate class and associate with proxy class private Object object; public Medium(Object object) { this.object = object; } /** * Create proxy class */ public Object getProxyInstance() { Enhancer en = new Enhancer(); //Set the bytecode of the delegate class en.setSuperclass(object.getClass()); //Set callback function en.setCallback(this); //Create proxy class return en.create(); } public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("Intermediary: lead clients to look around..."); System.out.println("Agent: sit down and negotiate with the client to sign the rental contract..."); //Tell the landlord it's paid Object invoke = method.invoke(object, args); return invoke; } }
Test method:
/** * @author Yang 33 * @date 2020/6/18 19:54 */ public class Demo { public static void main(String[] args) { //Delegation class Owner owner = new Owner(); //proxy class Owner proxyInstance = (Owner)new Medium(owner).getProxyInstance(); proxyInstance.money(); } }
Print results of running test method:
Agent: lead clients to look around Agent: sit down and sign a rental contract with the client Landlord: it's comfortable to lie down and earn money
summary
Static proxy requires both the delegate class and the proxy class to implement the same interface or inherit the same parent class.
jdk dynamic proxy class needs to implement interface or inherit parent class, but proxy class does not need.
Neither the proxy class nor the proxy class of cglib dynamic proxy need to implement the interface or inherit the parent class.
Link to the original text:
Source network, only for learning, if there is infringement, please contact delete.
I have compiled the interview questions and answers into PDF documents, as well as a set of learning materials, including Java virtual machine, spring framework, java thread, data structure, design pattern, etc., but not limited to this.
Focus on the official account [java circle] for information, as well as daily delivery of quality articles.