1. What is the proxy mode
Provide a proxy object for an object, through which the access to the original object can be controlled.
Popular explanation: One by one quick connection on our computer desktop, when we click this shortcut, we indirectly access this program.
2. Static proxy
What is static? That is, before the program runs, the proxy class has been written by the programmer and the .class file is generated
The following is the simplest example, the purpose: use the chicken proxy object to help us create the chicken animal
2.1 Simple code implementation of static proxy
First, create an interface that represents all animals and specifies all behaviors of animals
public interface Animal { void cry(); }
Let's create an entity of the proxy object, here we take chicken as an example
public class Chick implements Animal{ private String name; public Chick(String name) { this.name = name; birth(name); } private void birth(String name) { System.out.println("name is"+name+"the chicken was born"); } @Override public void cry() { System.out.println("i am a barking"+name+"chicken"); } }
The following is the proxy class of the animal chicken, which also needs to implement the Animal interface
public class ProxyChick implements Animal{ private String name; private Chick chick; public ProxyChick(String name) { this.name = name; } @Override public void cry() { if (chick==null){ chick = new Chick(name); } chick.cry(); } }
The test uses the chicken proxy class to get the chicken
public class ProxyTest { public static void main(String[] args){ ProxyChick chick = new ProxyChick("Cai Xukun"); chick.cry(); System.out.println("================"); chick.cry(); } }
2.2 Application in java
spring's Aop
Remember aspect-oriented programming? How did he realize the enhancement of the method? In fact, you only need to add the content to be enhanced before and after the proxy object calls the method of the proxy object.
We can write our enhanced logic at any position before and after the cry method. Next, we will use two print outputs to simulate the enhanced method.
public class ProxyChick implements Animal{ private String name; private Chick chick; public ProxyChick(String name) { this.name = name; } @Override public void cry() { if (chick==null){ chick = new Chick(name); } //enhance before method System.out.println("a real eel"); chick.cry(); //enhance after method System.out.println("learn to sing and dance rap play basketball"); } }
2.3 Advantages and disadvantages of static proxy
- advantage:
- Using the proxy mode brings high scalability to the program
- shortcoming:
- In order to implement the proxy pattern, brings additional work
- Since the proxy object needs to be passed before using the proxy object, it will increase the time overhead
- Using static proxies requires programmers to write a large number of proxy objects and increase workload
3. Dynamic proxy
Core: No need to create a proxy object for the class you want to proxy in advance
Key points of code implementation: Proxy class and InvocationHandler interface provided under java.lang.reflect package
The following is a simple dynamic proxy implementation process
3.1 Simple code implementation of dynamic proxy
The first few steps are similar to the static proxy. First, create an interface and define the behavior
public interface Animal { void cry(); }
Create the implementation class of the interface, that is, the proxied class
public class Chick implements Animal{ private String name; public Chick(String name) { this.name = name; birth(name); } private void birth(String name) { System.out.println("name is"+name+"the chicken was born"); } @Override public void cry() { System.out.println("i am a barking"+name+"chicken"); } }
Next, is the specific implementation of the dynamic proxy, creating the AnimalInvocationHandler class, which implements the InvocationHandler interface
Dynamic proxy process analysis:
1.AnimalInvocationHandler holds a proxy object
2. The method executed by the proxy object will be replaced by the invoke method in AnimalInvocationHandler
3. The proxy object will execute the method of the proxy object and other code statements in the invoke method in the invoke method
The above three steps are actually the main principle of Spring Aop
public class AnimalInvocationHandler<T> implements InvocationHandler { //hold a proxied object private T target; public AnimalInvocationHandler(T target) { this.target = target; } /** * Three of the parameters * proxy: An object representing this dynamic proxy * method: the method being executed * args: Parameters passed in when calling the method */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Proxy execution"+proxy.getClass().getName()+"Category"+method.getName()+"method"); Object invoke = method.invoke(target, args); System.out.println("Agent execution ends~"); return invoke; } }
test
public class DynamicProxyTest { public static void main(String[] args) { //Create a proxy object Animal chick = new Chick("Cai Xukun"); System.out.println("======================"); //Create an InvocationHandler, which is associated with the proxy object InvocationHandler chickHandler = new AnimalInvocationHandler<Animal>(chick); //Get the proxy object, and every method executed by the proxy object will be replaced by the invoke method in the InvocationHandler just now Animal chickProxy = (Animal) Proxy.newProxyInstance(Animal.class.getClassLoader(),new Class<?>[]{Animal.class},chickHandler); chickProxy.cry(); } }
Analysis of the above code: First, the chick object is the object that needs to be proxied. We pass the chick to the chickHandler, and when creating the proxy object chickProxy, the chickHandler is also passed in as a parameter. Finally, the method in the proxy object chickProxy is executed When, they are replaced by the invoke method in chickHandler.
3.2 Characteristics of dynamic proxy
- Unlike the static proxy, in the above code implementation, we did not see the specific proxy class. The proxied object and the proxy object in the dynamic proxy are proxyed through InvocationHandler, so there is no need to write one for each class. The proxy class only needs to be modified in the invoke method.