catalogue
I What is an agent
Imagine this scenario: we want to invite Jay to perform, but Jay only sings and doesn't want to do other trivial business. What else should we do at this time? At this time, of course, we need to find an agent to help Jay talk about salary, arrange itinerary and buy train tickets. This is equivalent to our agent model.
II Code implementation agent
First create the interface and implementation class of the target object
IJaySingService interface:
public interface IJaySingService { public String sing(String str); }
JaySingService implementation class:
public class JaySingService implements IJaySingService { @Override public String sing(String str) { if ("Flower Sea".equals(str) ) { System.out.println("Don't you leave~Distance is inseparable~"); return str; } else if ("Clearly".equals(str)) { System.out.println("Obviously, he is gentle~~~"); return str; } return "Can't sing~~~~"; } }
I Static proxy
Directly declare the proxy object as an exit, implement the interface of the target object, implement its methods and enhance them
StaticProxy static proxy class:
public class StaticProxy implements IJaySingService{ //The static proxy needs to inherit the target object and then override and enhance the method //Target object IJaySingService target; //Create constructor public StaticProxy(IJaySingService target) { this.target = target; } @Override public String sing(String str) { //What needs to be done before executing the target method System.out.println("You need to negotiate the performance fee with the agent before the performance"); String result = target.sing(str); //What needs to be done after executing the target method System.out.println("After singing, the agent needs to arrange the return trip back"); return result + "--Sounds good! Sounds good!"; } }
test:
public class Test01 { public static void main(String[] args) { //Create target object IJaySingService jaySingService = new JaySingService(); //Call static proxy for enhancements StaticProxy proxy = new StaticProxy(jaySingService); String result = proxy.sing("Flower Sea"); System.out.println(result); } }
result:
You need to negotiate the performance fee with the agent before the performance
Don't you leave ~ distance is inseparable~
After singing, the agent needs to arrange the return trip back
Huahai -- good! Sounds good!
II JDK dynamic agent
The flexibility of static agent is not high, so we introduce the way of dynamic agent
If the target object implements an interface, we can use the JDK proxy pattern. JDK dynamic proxy is equivalent to the interface to implement the target object, and then rewrite and enhance its methods.
public class Test02 { public static void main(String[] args) { //Get target object IJaySingService target = new JaySingService(); //Get dynamic proxy object IJaySingService proxy = (IJaySingService) Proxy.newProxyInstance(target.getClass().getClassLoader(),//Get class loader target.getClass().getInterfaces(), //Gets the interface of the target object new InvocationHandler() { //InvocationHandler class implementation //The invoke method is executed when the proxy object executes the method @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //What needs to be done before executing the target method System.out.println("You need to negotiate the performance fee with the agent before the performance"); //Call the method of the target object String result = (String) method.invoke(target,args); //What needs to be done after executing the target method System.out.println("After singing, the agent needs to arrange the return trip back"); return result + "--Nice to hear!Nice to hear"; } }); System.out.println(proxy.sing("Clearly")); } }
result:
You need to negotiate the performance fee with the agent before the performance
Obviously, he is gentle~~~
After singing, the agent needs to arrange the return trip back
It's -- it sounds good! Nice to hear
III CGLIB dynamic proxy
However, when the target object does not implement any interface, we can't use JDK dynamic proxy. Then we can only use CGLIB agent at this time. The essence of CGLIB is that its proxy class inherits the target object and overrides the related methods.
Create a target class VaeSingService without interface first:
public class VaeSingService { public String sing(String str) { if ("Why not".equals(str) ) { System.out.println("Sing this song for you~He has no style~Just means I want to give you happiness~"); return str; } return "Can't sing~~~~"; } }
Create a CGLIB proxy class to implement the MethodInterceptor interface and override its intercept interface:
I use a generic approach here
public class CglibProxy<T> implements MethodInterceptor { //Target object T target; public CglibProxy(T taget) { this.target = taget; } public T creatTaget() { Enhancer enhancer = new Enhancer(); //Specify parent class enhancer.setSuperclass(target.getClass()); //Specify callback method enhancer.setCallback(this); //Create proxy object return (T) enhancer.create(); } //Specific proxy methods to be executed @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //What needs to be done before executing the target method System.out.println("You need to negotiate the performance fee with the agent before the performance"); //Call the method of the target object String result = (String) method.invoke(target,objects); //What needs to be done after executing the target method System.out.println("After singing, the agent needs to arrange the return trip back"); return result + "--Nice to hear!Nice to hear"; } }
testVae:
public class Test03 { public static void main(String[] args) { //Target object VaeSingService target = new VaeSingService(); VaeSingService proxy = new CglibProxy<VaeSingService>(target).creatTaget(); System.out.println(proxy.sing("Why not")); } }
result:
You need to negotiate the performance fee with the agent before the performance
Sing this song for you ~ he has no style ~ it just means I want to give you happiness~
After singing, the agent needs to arrange the return trip back
Why not -- good! Nice to hear
testJay:
public class Test03 { public static void main(String[] args) { //Target object // VaeSingService target = new VaeSingService(); // VaeSingService proxy = new CglibProxy<VaeSingService>(target).creatTaget(); JaySingService target = new JaySingService(); JaySingService proxy = new CglibProxy<JaySingService>(target).creatTaget(); // System.out.println(proxy.sing("why not"); System.out.println(proxy.sing("Flower Sea")); } }
result:
You need to negotiate the performance fee with the agent before the performance
Don't you leave ~ distance is inseparable~
After singing, the agent needs to arrange the return trip back
Huahai -- good! Nice to hear