Proxy mode of Java design pattern, Java static proxy, Java Dynamic Proxy
================================
© Copyright sweet potato Yao 2021-06-21
https://blog.csdn.net/w995223851
1, Java static proxy
1. Define interface
public interface IHouse { //Sell the house void sale(); //View house information String house(); }
2. Proxied object class (actual operation class)
public class HouseOwner implements IHouse { @Override public void sale() { System.out.println(". . . I sold my house"); } @Override public String house() { return "The house is in Futian, Shenzhen. Price: 1.2 Hundred million"; } }
3. Agent class
public class HouseProxy implements IHouse { //Proxied object private HouseOwner houseOwner; public HouseProxy(HouseOwner houseOwner) { this.houseOwner = houseOwner; } @Override public void sale() { System.out.println("[What did the agent do before selling the house"); houseOwner.sale(); System.out.println("[How much commission do you charge after selling"); } @Override public String house() { return houseOwner.house(); } }
4. Testing
public class ProxyStatic { public static void main(String[] args) { HouseProxy houseProxy = new HouseProxy(new HouseOwner()); houseProxy.sale(); System.out.println("=============================="); System.out.println(houseProxy.house()); } }
result:
[What did the agent do before selling the house . . . I sold my house [How much commission do you charge after selling ============================== The house is in Futian, Shenzhen. Price: 1.2 Hundred million
2, Java} Jdk dynamic proxy
1. Dynamic proxy class
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyFactoryJdk{ private Object proxyTarget; public DynamicProxyFactoryJdk(Object proxyTarget) { this.proxyTarget = proxyTarget; } public Object getProxyInstance() { return Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(), proxyTarget.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("jdk Dynamic agent start"); System.out.println("method.getName()="+ method.getName()); Object returnObject = method.invoke(proxyTarget, args);//This is a proxyTarget object, not a proxy parameter System.out.println("jdk Dynamic agent end."); return returnObject; } }); } }
2. Testing
public class ProxyDynamicJdk { public static void main(String[] args) { //An object must be declared using an interface IHouse proxyTarget = new HouseOwner(); //An object must be declared using an interface IHouse houseProxy = (IHouse) new DynamicProxyFactoryJdk(proxyTarget).getProxyInstance(); System.out.println("+++++++++++++++++++++++++++++++"); System.out.println("houseProxy=" + houseProxy); System.out.println("houseProxy.getClass().getName()=" + houseProxy.getClass().getName()); System.out.println("=============================="); houseProxy.sale(); System.out.println("=============================="); System.out.println(houseProxy.house()); } }
result:
+++++++++++++++++++++++++++++++ jdk Dynamic agent start method.getName()=toString jdk Dynamic agent end. houseProxy=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner@6bc7c054 houseProxy.getClass().getName()=com.sun.proxy.$Proxy0 ============================== jdk Dynamic agent start method.getName()=sale . . . I sold my house jdk Dynamic agent end. ============================== jdk Dynamic agent start method.getName()=house jdk Dynamic agent end. The house is in Futian, Shenzhen. Price: 1.2 Hundred million
3, Java cglib dynamic proxy
1. Dynamic proxy class (cglib related packages need to be introduced)
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * cglib package needs to be introduced * */ public class DynamicProxyFactoryCglib implements MethodInterceptor{ private Object proxyTarget; public DynamicProxyFactoryCglib(Object proxyTarget) { this.proxyTarget = proxyTarget; } public Object getProxyInstance() { return Enhancer.create(proxyTarget.getClass(), this); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("cglib Dynamic agent start"); System.out.println("method.getName()="+ method.getName()); Object returnObject = method.invoke(proxyTarget, args);//This is a proxyTarget object, not an obj parameter System.out.println("cglib Dynamic agent end."); return returnObject; } }
2. Testing
public class ProxyDynamicCglib { public static void main(String[] args) { HouseOwner houseOwner = (HouseOwner) new DynamicProxyFactoryCglib(new HouseOwner()).getProxyInstance(); System.out.println("+++++++++++++++++++++++++++++++"); System.out.println("houseOwner=" + houseOwner); System.out.println("houseOwner.getClass().getName()=" + houseOwner.getClass().getName()); System.out.println("=============================="); houseOwner.sale(); System.out.println("=============================="); System.out.println(houseOwner.house()); } }
result:
+++++++++++++++++++++++++++++++ cglib Dynamic agent start method.getName()=toString cglib Dynamic agent end. houseOwner=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner@6842775d houseOwner.getClass().getName()=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner$$EnhancerByCGLIB$$8067e885 ============================== cglib Dynamic agent start method.getName()=sale . . . I sold my house cglib Dynamic agent end. ============================== cglib Dynamic agent start method.getName()=house cglib Dynamic agent end. The house is in Futian, Shenzhen. Price: 1.2 Hundred million
4, Summary
Static proxy:
The implementation is relatively simple. As long as a proxy object is declared to wrap the target object, the proxy function can be realized, but the static proxy can only serve one target object. If there are too many target objects, many proxy classes will be generated.
Static agent generates class bytecode file during compilation, which can be used directly and has high efficiency.
JDK dynamic agent:
The target object needs to implement the business interface (the target class and proxy class must implement the same interface), and the proxy class only needs to implement the InvocationHandler interface.
The dynamic agent must implement the InvocationHandler interface. By reflecting the agent method, the system performance is consumed, but the number of agent classes can be reduced and the use is more flexible.
cglib dynamic proxy:
cglib (Code Generation Library) is a third-party code generation class library, which dynamically generates a subclass object in memory at runtime, so as to expand the function of the target object.
Using cglib requires introducing the jar package of cglib
Cglib proxy does not need to implement the interface. It implements the proxy by generating class bytecode, which is slightly faster than reflection, and there is no performance problem. However, cglib inherits the target object and needs to rewrite the method, so the target object cannot be final.
The object using cglib proxy does not need to implement the interface, so that the proxy class does not invade.
================================
© Copyright sweet potato Yao 2021-06-21