Proxy is a structural design model that mainly solves the problems caused by direct object access. Proxy is divided into static proxy and dynamic proxy (JDK proxy and CGLIB proxy).
Static proxy: Proxy classes created by programs, or specific tool classes, are often used in normal development. This kind of proxy mode usually generates corresponding class files before the program runs.
Dynamic proxy: Create dynamically when a program is running through a reflection mechanism.
The following three proxies are implemented through a scenario
- Step 1: Define the store interface (Subject)
- Step 2: RealSubject
- Step 3: Platform Operations (proxy)
- Step 4: Individual consumption (client)
Subject, RealSubject are used in several proxy methods, and are now defined here
Store.java(Subject): Defines two interfaces, operation and business.
public interface Store { /** * Shop Operations */ public void operate(); /** * Shop Dealing */ public void business(); }
PersonStore.java(RealSubject) Single User Operations
public class PersonStore implements Store { @Override public void operate() { System.out.println("Personal store operations"); } @Override public void business() { System.out.println("Personal Store Transactions"); } }
Static Proxy
The implementation of static proxy is simple. The proxy class maintains a proxy object in the class by implementing the same interface as the target object. This scenario is used in cases where there are few individual businesses. If there are many proxy classes, they are very numerous and difficult to maintain.
Create static proxy class
ProxyStroe.java(proxy): Operating on a proxy platform charges an administrative fee of 100. This proxy class implements the Store interface and sets a target class (PersonStore).
public class ProxyStroe implements Store{ private Store personStore = new PersonStore(); @Override public void operate() { System.out.println("Charge management fee of 100 yuan"); personStore.operate(); } @Override public void business() { personStore.business(); } }
Static Proxy Call
StaticConsumer.java(client): ProxyStroe is created to proxy and operate on PersonStore.
public class StaticConsumer { public static void main(String[] args) { ProxyStroe store = new ProxyStroe(); store.operate(); store.business(); } }
Dynamic Proxy
JDK Proxy
Dynamic proxy classes are implemented through interfaces, using interceptors (which must implement InvocationHanlder) plus a reflection mechanism to generate an anonymous class that implements proxy interfaces.
InvokeHandler is called to process before calling the specific method.
Create jdk proxy class
JDKStoreHandler.java(proxy): By implementing the invoke method of the InvocationHandler interface, a reflection call is made inside, and newProxyInstanse creates a real object from the target object.
public class JDKStoreHandler implements InvocationHandler { /** * Target object */ private Object targetObject; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("operate".equals(method.getName())){ System.out.println("Charge management fee of 100 yuan"); } return method.invoke(targetObject, args); } /** * * @param targetObject * @return */ public Object newProxyInstanse(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this); } }
JDK Proxy Object Call
JDKDynamicConsumer.java(proxy): Create a real target object through newProxyInstance of JDKStoreHandler and invoke the method of the interface
public class JDKDynamicConsumer { public static void main(String[] args) { Store store = (Store)new JDKStoreHandler().newProxyInstanse(new PersonStore()); store.operate(); store.business(); } }
CGLIB Proxy
The cglib dynamic proxy uses the asm open source package to load in the class file of the proxy object class and generate subclasses by modifying its byte code.
Create cglib proxy object
CglibProxy.java(proxy): You need to implement MethodInterceptor's intercept method and make a reflection call.Create real objects from createProxyObject, where objects are generated directly from the target object.
public class CglibProxy implements MethodInterceptor{ /** * CGlib Target object requiring proxy */ private Object targetObject; public Object createProxyObject(Object targetObject){ this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetObject.getClass()); enhancer.setCallback(this); Object proxyObj = enhancer.create(); return proxyObj; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if("operate".equals(method.getName())){ System.out.println("Charge management fee of 100 yuan"); } return method.invoke(targetObject, objects); } }
CGLib Proxy Object Call
CglibDynamicConsumer.java(client): Create a real target object through CglibProxy's createProxyObject and make method calls to it
public class CglibDynamicConsumer { public static void main(String[] args) { Store store = (Store)new CglibProxy().createProxyObject(new PersonStore()); store.operate(); store.business(); } }
Source uploaded: https://github.com/itrickzhan...