Design pattern - proxy pattern (static proxy, dynamic proxy, cglib proxy)

Article directory

proxy pattern

Proxy pattern is a structural pattern. The proxy pattern provides a surrogate for an object to control access to that object. That is, access to the target object through the proxy object can enhance additional function operations on the basis of the realization of the target object, that is, expand the function of the target object.

The proxied object can be a remote object, an object with creation cost or an object requiring security control. There are three main proxy modes: static proxy, dynamic proxy (also known as JDK proxy and interface proxy) and cglib proxy (creating objects dynamically in memory without implementing interfaces can also belong to the category of dynamic proxy)

Class diagram:

Static proxy

Static proxy defines a parent class or interface, and then the proxy object (i.e. the target object) implements the same interface or inherits the same parent class with the proxy object. The proxy object implements the same interface as the target object, and then calls the method of the target object by calling the same method.

  • Advantages: the target function can be extended through the proxy object without modifying the function of the target object.
  • Disadvantages: because the proxy object needs to implement the same interface as the target object, there will be many proxy classes. Once methods are added to the interface, both the target object and the proxy object must be maintained.

For example, the case of substitute teachers:

  • ITeacherDao: Interface
  • TeacherDao: target object that implements the interface ITeacherDao
  • TeacherDAOProxy: a proxy object, which also implements the ITeacherDao interface, aggregates the ITeacherDao attribute, passes the parameter setting value through the constructor, and calls the target object by calling the method of the proxy object.

code

  1. Interface
public interface ITeacherDao {
	void teach(); // Teaching methods
}
copy
  1. Proxied object
public class TeacherDao implements ITeacherDao {
	@Override
	public void teach() {
		System.out.println("One button three connections");
	}
}
copy
  1. Proxy object
public class TeacherDaoProxy implements ITeacherDao {
	private ITeacherDao target; //Aggregate target objects through interfaces
	public TeacherDaoProxy(ITeacherDao target) {
		this.target = target;
	}
	@Override
	public void teach() { //Rewrite interface
		System.out.println("Static proxy start");
		target.teach();
		System.out.println("Static proxy end");
	}
}
copy
  1. test
public class Client {
	public static void main(String[] args) {
		//Create proxied object
		TeacherDao teacherDao = new TeacherDao();

		//Create a proxy object and pass the proxy object to the proxy object at the same time
		TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);

		//Call the method of the proxy object through the proxy object
		teacherDaoProxy.teach();
	}
}
/*Operation results:
Static proxy start
 One button three connections
 Static proxy end
*/
copy

Dynamic proxy

Dynamic proxy is also called JDK proxy and interface proxy. It makes the proxy object do not need to implement the interface (but the target object needs to implement the interface). The generation of proxy object is to use the JDK API to dynamically build proxy objects in memory.

That is, use the JDK package java lang.reflect. The newProxyInstance method in proxy is used to dynamically create the target object (proxied object). This method needs to receive three parameters as follows:

  1. ClassLoader loader Specifies the class loader used by the current target object
  2. Class<?>[] interfaces The interface type implemented by the target object. Use generic methods to confirm the type
  3. InvocationHandler h Event processing: when executing the method of the target object, the event handler method will be triggered, and the currently executing target object method will be passed in as a parameter
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
copy

Class diagram:

The core is getProxyInstacne()

  1. TeacherDao target object based on the passed in object
  2. Use the return mechanism to return a proxy object
  3. Then, the target object method is called through the proxy object

code:

  1. Interface
public interface ITeacherDao {
	void teach();
	void tesst(String name);
}
copy
  1. Target object
public class TeacherDao implements ITeacherDao {
	@Override
	public void teach() {
		System.out.println("One button three connections");
	}
	@Override
	public void tesst(String name) {
		System.out.println("Parameter transmission test:" + name);
	}
}
copy

(insert anti crawl information) CSDN address of blogger: https://wzlodq.blog.csdn.net/

  1. Proxy object
public class ProxyFactory {
	//Maintain a target Object, Object
	private Object target;
	//Constructor to initialize the target
	public ProxyFactory(Object target) {
		this.target = target;
	}
	//Dynamically generate a proxy object
	public Object getProxyInstance() {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(),
				new InvocationHandler() { //Anonymous class overrides invoke method
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("Dynamic proxy start");
						Object returnVal = method.invoke(target, args);//Reflection mechanism calls the method of the target object
						System.out.println("Dynamic proxy end");
						return returnVal;
					}
				});
	}
}
copy
  1. test
public class Client {
	public static void main(String[] args) {
		//Create target object
		ITeacherDao target = new TeacherDao();

		//Create proxy object
		ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();

		//Proxy objects are dynamically generated in memory
		System.out.println(proxyInstance.getClass());

		//Call the method of the target object through the proxy object
		proxyInstance.teach();
		proxyInstance.tesst("One button three connections");
	}
}
/*Operation results:
Dynamic proxy start
 One button three connections
 Dynamic proxy end
 Dynamic proxy start
 Parameter transmission test: one key and three connections
 Dynamic proxy end
*/
copy

cglib proxy

Cglib proxy is also called subclass proxy. It makes the target object do not need to implement interfaces. It builds a subclass object in memory to extend the function of the target object. Some also attribute cglib proxy to dynamic proxy.

Cglib is a high-performance code generation package that can extend java classes and implement java interfaces at run time. It is used by many AOP frameworks (such as Spring AOP). The bottom layer of cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM.

Special note: the proxy class cannot be final, or an error java Lang.illegalargumentexception: if the method of the target object is final or static, it will not be intercepted (that is, additional business methods of the target object will not be executed).

Add cglib package: Download the following jar package, copy it to the project, and right-click add to library. https://github.com/wuzelong/CSDNBLOG (by the way, ask for a star)

The difference is that the proxy object implements the MethodInterceptor interface and rewrites the intercept() method to call the methods of the proxy object (target object).

code:

  1. Target object
public class TeacherDao {
	public String teach() {
		System.out.println("One button three connections");
		return "good";
	}
}
copy
  1. Proxy object
public class ProxyFactory implements MethodInterceptor {
	//Target object
	private Object target;
	public ProxyFactory(Object target) {
		this.target = target;
	}
	//Returns the proxy object of the target object
	public Object getProxyInstance() {
		//Create a tool class
		Enhancer enhancer = new Enhancer();

		//Set parent class
		enhancer.setSuperclass(target.getClass());

		//Set callback function
		enhancer.setCallback(this);

		//Create a subclass object, the proxy object
		return enhancer.create();
	}
	//If you override the intercept method, the method of the target object will be called
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		System.out.println("Cglib Agent start");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib Agent end");
		return returnVal;
	}
}
copy
  1. test
public class Client {
	public static void main(String[] args) {
		//Create target object
		TeacherDao target = new TeacherDao();

		//Gets the proxy object and passes the target object to the proxy object
		TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance();

		//Execute the method of the proxy object and trigger the concept method to call the target object
		proxyInstance.teach();
		System.out.println(res);
	}
}
/*Operation results:
Cglib Agent start
 One button three connections
Cglib Agent end
 good
*/
copy

application

  • Firewall proxy The intranet penetrates the firewall through the proxy to access the public network.
  • Cache proxy When requesting resources, first fetch them from the cache agent. If not, then fetch them from the database or the public network, and then update the cache (such as Redis).
  • Remote agent Communicate information with real remote objects through the network (such as remote connection server).
  • Synchronization agent Used in multithreaded programming to complete the synchronization between multithreads.

Posted by new7media on Wed, 01 Jun 2022 19:33:08 +0530