Proxy mode

Introduction to agent mode

  • Proxy mode: provide an avatar for an object to control access to the object. That is, the target object is accessed through the proxy object
  • The advantage is that on the basis of the realization of the target object, additional function operations can be enhanced, that is, the function of the target object can be extended
  • The proxied object can be a remote object, an object with high creation cost or an object requiring security control
  • The proxy mode has different forms, mainly including three kinds of static proxy, dynamic proxy (JDK proxy, interface proxy) and Cglib proxy (it can dynamically create objects in memory without implementing interfaces. It belongs to the category of dynamic proxy)

Static proxy

When using a static proxy, you need to define an interface or parent class. The proxy object (i.e. the target object) and the proxy object implement the same interface or inherit the same parent class together

  • Define an interface: ITeacherDao
  • The target object TeacherDAO implements the interface ITeacherDAO
  • Using the static proxy method, you need to implement ITeacherDAO in the proxy object TeacherDAOProxy
  • When called, the target object is called by calling the method of the proxy object
  • The proxy object and the target object should implement the same interface, and then call the method of the target object by calling the same method
//Interface
public interface ITeacherDao {
	void teach(); // Teaching methods
}
public class TeacherDao implements ITeacherDao {
	@Override
	public void teach() {
		System.out.println(" In the course of teaching.....");
	}
}
//Proxy object, static proxy
public class TeacherDaoProxy implements ITeacherDao{
	private ITeacherDao target; // Target object, aggregated through interface
	//constructor 
	public TeacherDaoProxy(ITeacherDao target) {
		this.target = target;
	}
	@Override
	public void teach() {
		System.out.println("Start agent to complete some operations..... ");//method
		target.teach();
		System.out.println("Submit.....");//method
	}
}
public class Client {
	public static void main(String[] args) {
		//Create target object (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);
		//Through the proxy object, call the method of the proxy object
		//That is, the method of the proxy object is executed, and the proxy object calls the method of the target object 
		teacherDaoProxy.teach();
	}
}

advantage

  • Without modifying the function of the target object, the target function can be extended through the proxy object
    shortcoming
  • Because the proxy object needs to implement the same interface as the target object, there will be many proxy classes
  • Once a method is added to the interface, both the target object and the proxy object must be maintained

Dynamic agent

  • The proxy object does not need to implement the interface, but the target object needs to implement the interface, otherwise the dynamic proxy cannot be used
  • The generation of proxy object is to dynamically build proxy object in memory by using JDK API
  • Dynamic agent is also called JDK agent and interface agent

JDK dynamic proxy application instance

API for generating proxy objects in JDK

  • Package of proxy class: Java lang.reflect. Proxy
  • The JDK implementation agent only needs to use the newProxyInstance method, but this method needs to receive three parameters. The complete writing method is: static object newProxyInstance (classiloader loader, class <? > [] interfaces, invocationhandler h)

//Interface
public interface ITeacherDao {
	void teach(String name); // Training Methods 
}
public class TeacherDao implements ITeacherDao {
	@Override
	public void teach(String name) {
		System.out.println(name+" In Teaching.... ");
	}
}
public class ProxyFactory {
	//Maintain a target Object, Object
	private Object target;
	//Constructor to initialize the target
	public ProxyFactory(Object target) { this.target = target; }
	//Generate a proxy object for the target object
	public Object getProxyInstance() {
		/*
		 *  public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
         *  1. ClassLoader loader :  Specifies the class loader used by the current target object, and the method to get the loader is fixed
         *  2. Class<?>[] interfaces: The interface type implemented by the target object, and use the generic method to confirm the type
		 *  3. InvocationHandler h : In event processing, when executing the method of the target object, the event processor method will be triggered, and the currently executed target object method will be passed in as a parameter
		 */
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("JDK Agent start~~");
						//The reflection mechanism calls the method of the target object
						Object returnVal = method.invoke(target, args);
						System.out.println("JDK Agent submission");
						return returnVal;
					}
				}); 
	}
}
public class Client {
	public static void main(String[] args) {
		//Create target object
		ITeacherDao target = new TeacherDao();
		//Create a proxy object for the target object, which can be converted to ITeacherDao
		ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
		// proxyInstance=class com. sun. proxy.$ Proxy objects are dynamically generated in proxy0 memory
		System.out.println("proxyInstance=" + proxyInstance.getClass());
		//Call the method of the target object through the proxy object
		//proxyInstance.teach();
		proxyInstance.teach(" tom ");
	}
}

Cglib proxy application instance

  • Both static proxy and JDK proxy modes require the target object to implement an interface, but sometimes the target object is only a separate object and does not implement any interface. At this time, the target object subclass can be used to implement the proxy, which is Cglib proxy
  • Cglib agent is also called subclass agent. It constructs a subclass object in memory to expand the function of the target object. Some books also attribute cglib agent to dynamic agent.
  • Cglib is a powerful and high-performance code generation package, which can extend java classes and implement java interfaces at run time It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception
  • How to select agent mode in AOP programming:
    • The target object needs to implement the interface and use JDK proxy
    • The target object does not need to implement the interface and uses Cglib proxy
  • The bottom layer of Cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM

If you use eclipse, you need to add the following jar packages

  • Dynamically build subclasses in memory. Note that the class of the agent cannot be final, otherwise an error Java. Net will be reported lang.IlegalArgumentException
  • If the method of the target object is final/static, it will not be intercepted, that is, additional business methods of the target object will not be executed
  • getProxyInstance creates a proxy object for the target object target
	//Returns a proxy object: the proxy object of the target object
	public Object getProxyInstance() {
		//1. Create a tool class
		Enhancer enhancer = new Enhancer();
		//2. Set parent class
		enhancer.setSuperclass(target.getClass());
		//3. Set callback function
		enhancer.setCallback(this);
		//4. Create a subclass object, that is, a proxy object
		return enhancer.create();
	}
  • Override the intercept method to call the proxy object (target object) method
	//Overriding the intercept method will call the method of the target object
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("Cglib proxy pattern ~~ start");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib proxy pattern ~~ Submit");
		return returnVal;
	}

idea import pom dependency

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>
public class TeacherDao {
	public String teach() {
		System.out.println(" Yes, I am cglib Proxy, no need to implement interface ");
		return "hello";
	}
}
public class ProxyFactory implements MethodInterceptor {
	//Maintain a target object
	private Object target;
	//Constructor, passing in an object to be represented
	public ProxyFactory(Object target) {
		this.target = target;
	}
	//Returns a proxy object: the proxy object of the target object
	public Object getProxyInstance() {
		//1. Create a tool class
		Enhancer enhancer = new Enhancer();
		//2. Set parent class
		enhancer.setSuperclass(target.getClass());
		//3. Set callback function
		enhancer.setCallback(this);
		//4. Create a subclass object, that is, a proxy object
		return enhancer.create();
	}
	//Overriding the intercept method will call the method of the target object
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("Cglib proxy pattern ~~ start");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib proxy pattern ~~ Submit");
		return returnVal;
	}
}
public class Client {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//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
		String res = proxyInstance.teach();
		System.out.println("res=" + res);
	}
}

Several common agent models introduce one or more variants

Firewall agent
The intranet penetrates the firewall through the agent to realize the access to the public network.
Cache agent
For example, when requesting resources such as picture files, go to the cache agent first. If you get the resources, ok. If you can't get the resources, go to the public network or database, and then cache.
Remote agent
The local representative of the remote object, through which the remote object can be called as a local object. Remote agents communicate information with real remote objects through the network.
Synchronization agent
It is mainly used in multithreaded programming to complete the synchronization between multithreads

Keywords: Java

Added by Avochelm on Tue, 15 Feb 2022 04:22:40 +0200