Java proxy mode (static proxy, dynamic proxy, cglib proxy)

Time:2022-9-21

proxy mode

Proxy Pattern is a structural pattern. The proxy pattern provides a stand-in for an object to control access to that object. That is, accessing the target target object through the proxy object can enhance additional functional operations based on 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 a cost to create, or an object that requires security control. There are three main forms of proxy mode, namely static proxy, dynamic proxy (also known as JDK proxy, interface proxy) and cglib proxy (dynamically create objects in memory without implementing interfaces, and can also belong to the category of dynamic proxy)

Class Diagram:

在这里插入图片描述

static proxy

Static proxy is to define a parent class or interface, and then the proxy object (that is, the target object) implements the same interface or inherits the same parent class together with the proxy object. The proxy object implements the same interface as the target object, and then invokes the target object's methods by calling the same method.

  • Advantages: The function of the target object can be extended 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 the interface adds methods, the target object and the proxy object must be maintained.

For example, the case of a teacher substitute:

在这里插入图片描述

  • ITeacherDao: Interface
  • TeacherDao: the target object, which implements the interface
  • ITeacherDaoTeacherDAOProxy: The proxy object also implements the ITeacherDao interface, aggregates the ITeacherDao attribute, and sets the value through the constructor. When calling, the target object is called by calling the method of the proxy object.

code

interface

public interface ITeacherDao {
	void teach(); // method of teaching
}

proxied object

public class TeacherDao implements ITeacherDao {
	@Override
	public void teach() {
		System.out.println("One-key three-link");
	}
}

proxy object

public class TeacherDaoProxy implements ITeacherDao {
	private ITeacherDao target; //Aggregate the target object through the interface
	public TeacherDaoProxy(ITeacherDao target) {
		this.target = target;
	}
	@Override
	public void teach() { //Rewrite the interface
		System.out.println("Static proxy started");
		target.teach();
		System.out.println("End of static proxy");
	}
}

test

public class Client {
	public static void main(String[] args) {
		//create the proxy object
		TeacherDao teacherDao = new TeacherDao();
		//Create a proxy object and pass the proxy object to the proxy object
		TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
		//Through the proxy object, call the method of the proxy object
		teacherDaoProxy.teach();
	}
}
/*operation result:
Static proxy starts
One button three links
Static proxy ends
*/

Dynamic proxy

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

i.e. using JDK packagesjava.lang.reflect.ProxyneutralnewProxyInstanceThe method to dynamically create the target object (proxy object), the 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 the generic method to confirm the type

3.InvocationHandler h event processing, when the method of the target object is executed, the event handler method will be triggered, and the currently executed target object method will be passed in as a parameter


static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

Class Diagram:

在这里插入图片描述

core isgetProxyInstacne()

  • According to the incoming object TeacherDao target object
  • Use the return mechanism to return a proxy object
  • Then through the proxy object, call the target object method

Code:

interface


public interface ITeacherDao {
	void teach();
	void tesst(String name);
}

target

public class TeacherDao implements ITeacherDao {
	@Override
	public void teach() {
		System.out.println(&quot;One-key three-link&quot;);
	}
	@Override
	public void tesst(String name) {
		System.out.println(&quot;parameter test: &quot; + name);
	}
}

proxy object

public class ProxyFactory {
	//Maintain a target object, Object
	private Object target;
	//Constructor, initialize 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 the invoke method
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println(&quot;Dynamic proxy start&quot;);
						Object returnVal = method.invoke(target, args);//The reflection mechanism calls the method of the target object
						System.out.println(&quot;End of dynamic proxy&quot;);
						return returnVal;
					}
				});
	}
}

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();
		//The proxy object is dynamically generated in memory
		System.out.println(proxyInstance.getClass());
		// Through the proxy object, call the method of the target object
		proxyInstance.teach();
		proxyInstance.tesst(&quot;One-click three connections&quot;);
	}
}
/*operation result:
Dynamic proxy starts
One button three links
Dynamic proxy ends
Dynamic proxy starts
传参测试:One button three links
Dynamic proxy ends
*/

cglib proxy

Cglib proxy is also called subclass proxy, it makes the target object do not need to implement the interface, it builds a subclass object in memory to realize the function extension of the target object, and some also attribute the Cglib proxy to the dynamic proxy.

Cglib is a high-performance code generation package that extends Java classes and implements Java interfaces at runtime. Used by many AOP frameworks (eg Spring AOP). The bottom layer of the Cglib package is to convert bytecode and generate new classes by using the bytecode processing framework ASM.

Special attention: the class of the proxy cannot be final, otherwise an error will be reportedjava.lang.IllegalArgumentException, if the method of the target object is final or static, it will not be intercepted (that is, the additional business methods of the target object will not be executed).

Add the cglib package: Download the following jar package, copy it to the project, then right-clickadd to library

在这里插入图片描述

在这里插入图片描述

The difference is that the proxy object implementsMethodInterceptorinterface, rewrittenintercept()The method implements a method call to the proxied object (target object).

Code:

target

public class TeacherDao {
	public String teach() {
		System.out.println(&quot;One-key three-link&quot;);
		return &quot;OK&quot;;
	}
}

proxy object

public class ProxyFactory implements MethodInterceptor {
	//target
	private Object target;
	public ProxyFactory(Object target) {
		this.target = target;
	}
	//Return the proxy object of the target object
	public Object getProxyInstance() {
		//create a tool class
		Enhancer enhancer = new Enhancer();
		//set the parent class
		enhancer.setSuperclass(target.getClass());
		//set callback function
		enhancer.setCallback(this);
		//Create a subclass object, that is, a proxy object
		return enhancer.create();
	}
	//Rewrite the intercept method, which will call the method of the target object
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		System.out.println(&quot;Cglib agent started&quot;);
		Object returnVal = method.invoke(target, args);
		System.out.println(&quot;Cglib proxy ended&quot;);
		return returnVal;
	}
}

test

public class Client {
	public static void main(String[] args) {
		//create target object
		TeacherDao target = new TeacherDao();
		//Get the proxy object and pass the target object to the proxy object
		TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance();
		//Execute the method of the proxy object, trigger the intercept method, so as to realize the call to the target object
		proxyInstance.teach();
		System.out.println(res);
	}
}
/*operation result:
Cglib agent starts
One button three links
Cglib proxy ends
it is good
*/

application

  • Firewall proxy
  • The intranet penetrates the firewall through the proxy to achieve access to the public network.
  • caching proxy
  • When requesting resources, first go to the cache proxy to get them. If you can't get them, go to the database or public network to get them, and then update the cache (such as Redis). remote proxy
  • Communicate information with real remote objects over the network (such as remote connections to servers).
  • Sync agent
  • Used in multi-threaded programming to complete synchronization work between multiple threads.

Summarize

This article is here, I hope it can help you, and I hope you can pay more attention to more content of developpaer!