This article brings you relevant knowledge about java. Dynamic proxy refers to the relationship between the proxy class and the target class that is determined when the program is running, and the customer calls it through the proxy class. The method of the target object is to dynamically create a proxy object of the target class as needed when the program is running. The following will explain the principle and implementation of Java dynamic proxy in detail through cases. I hope it will be helpful to everyone.
Recommended study: "java video tutorial"
I believe everyone is familiar with the word "agent". To put it simply, it is Sell goods on behalf of manufacturers, agents sell goods on behalf of manufacturers, and customers find agents to purchase goods. That is to say: 1) The relationship between the customer and the manufacturer is invisible, and the customer does not know who the manufacturer is behind it. 2) Agents can "position" customers and sell to the customer groups in need more accurately.
Proxy mode: Provide a proxy for other objects to control access to this object, that is, create a proxy object as an intermediary between the client and the target object, mainly The purpose is to protect the target object or enhance the target object
By using the proxy mode, there are usually two advantages:
\1) The implementation of the proxy class can be hidden
\ 2) It can realize the decoupling between the client and the proxy class, and can do some additional processing without modifying the code of the proxy class
The so-called dynamic proxy is By declaring a clear proxy class to access the source object, one proxy can only serve one product. When there are n products, n proxies are needed, which is not conducive to business development.
Example: We have two interfaces, Mouse and Keyboard, each interface has an implementation class
The code in the implementation class is as follows:
public class LogitechMouse implements Mouse{ @Override public void sell() { System.out.println("出售罗技鼠标"); } } public class HHKBKeyboard implements Keyboard{ @Override public void sell() { System.out.println("出售HHKB键盘"); } }
Now what we have to do is to let the agent output a sentence of pre-sales understanding before calling sell()
, and a sentence of after-sales service after calling
Then we only need to write two proxy classes MouseProxy
and KeyboardProxy
public class MouseProxy implements Mouse { private Mouse mouse; public MouseProxy(Mouse mouse) { this.mouse = mouse; } @Override public void sell() { System.out.println("售前了解"); mouse.sell(); System.out.println("售后服务"); } } public class KeyboardProxy implements Keyboard{ private Keyboard keyboard; public KeyboardProxy(Keyboard keyboard) { this.keyboard = keyboard; } @Override public void sell() { System.out.println("售前了解"); keyboard.sell(); System.out.println("售后服务"); } }
The final execution is:
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); MouseProxy mouseProxy = new MouseProxy(logitechMouse); mouseProxy.sell(); Keyboard hhkbKeyboard = new HHKBKeyboard(); KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard); keyboardProxy.sell(); } }
Output:
Pre-sales understanding
Logitech mouse for sale
After-sales service
Pre-sales understanding
HHKB keyboard for sale
After-sales service
The code of the static agent is very simple and easy to understand , although this model is good, it also has obvious shortcomings:
Then you can use dynamic proxy to solve the problem at this time
The way the proxy class creates the proxy when the program is running is called dynamic proxy, that is It is said that the proxy class is not defined in the java code, but is dynamically generated at runtime.
JDK has supported the creation of dynamic proxy classes since version 1.3. There are only two main core classes: java.lang.reflect.Proxy
and java.lang.reflect.InvocationHandler
Still the above example, use JDK dynamic proxy as follows :
public class JDKProxy implements InvocationHandler { private Object object; public JDKProxy(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, args); System.out.println("售后服务"); return invoke; } }
When we call the method of the proxy class object, this "call" will be transferred to the invoke method,
The proxy class object is passed in as the proxy parameter,
The parameter method identifies which method of the proxy class we are specifically calling, and
args are the parameters of this method.
In this way, all our calls to methods in the proxy class will become calls to invoke, so that we can add unified processing logic to the invoke method (we can also use different proxies based on the method parameters) class methods do different processing). Therefore, we can implement pre-sales understanding in the invoke method of the intermediary class, then call the method of the proxy class, and then provide after-sales service.
Execute the code
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); JDKProxy jdkProxy = new JDKProxy(logitechMouse); Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy); mouse.sell(); HHKBKeyboard hhkbKeyboard = new HHKBKeyboard(); JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard); Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1); keyboard.sell(); } }
You can see that no matter how many interfaces there are, only one proxy class is needed.
Agent class:
public class CGLIBProcy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); private Object object; public CGLIBProcy(Object object) { this.object = object; } public Object getProxy(){ //设置需要创建子类的类 enhancer.setSuperclass(object.getClass()); enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } // o: cglib 动态生成的代理类的实例 // method:实体类所调用的都被代理的方法的引用 // objects 参数列表 // methodProxy:生成的代理类对方法的代理引用 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, objects); System.out.println("售后处理"); return invoke; } }
Execution code:
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse); Mouse proxy = (Mouse)cglibProcy.getProxy(); proxy.sell(); cglibProcy = new CGLIBProcy(new HHKBKeyboard()); Keyboard keyboard = (Keyboard)cglibProcy.getProxy(); keyboard.sell(); } }
Recommended learning: "java video tutorial"
The above is the detailed content of Complete mastery of Java dynamic proxies. For more information, please follow other related articles on the PHP Chinese website!