Design mode structural mode agent mode

Basic introduction of agent mode

1) Proxy mode: provides a surrogate for an object to control access to that object. That is, access the target object through the proxy object. The advantage of doing this is: on the basis of the realization of the target object, you can enhance the additional function operation, that is, extend the function of the target object.
2) The proxied object can be a remote object, an expensive object to create, or an object requiring security control
3) There are three kinds of agent patterns: static agent, dynamic agent (JDK agent, interface agent) and Cglib agent (which can dynamically create objects in memory without implementing interfaces, which belong to the category of dynamic agent).

Basic introduction of static code pattern
When using static proxy, you need to define the interface or parent class. The proxy object (i.e. the target object) implements the same interface or inherits the same parent class together with the proxy object.

Advantages and disadvantages of static agent
1) Advantage: it can extend the target function through the proxy object without modifying the function of the target object
2) Disadvantage: because the proxy object needs the same interface as the target object, there will be many proxy classes
3) Once a method is added to the interface, both the target object and the proxy object must be maintained

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

//Interface
public interface ITeacherDao {
	
	void teach(); // Teaching methods
}
public class TeacherDao implements ITeacherDao {

	@Override
	public void teach() {
		// TODO Auto-generated method stub
		System.out.println(" The teacher is teaching.....");
	}

}
//Proxy object, static proxy
public class TeacherDaoProxy implements ITeacherDao{
	private ITeacherDao target; // Target objects, aggregating through interfaces
	//constructor
	public TeacherDaoProxy(ITeacherDao target) {
		this.target = target;
	}

	@Override
	public void teach() {
		// TODO Auto-generated method stub
		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) {
		// TODO Auto-generated method stub
		//Create target object (proxied object)
		TeacherDao teacherDao = new TeacherDao();
		//Create a proxy object and pass the proxied object to the proxy object
		TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
		//Through the proxy object, call the method to the proxy object
		//That is, the method of the proxy object is executed, and then the proxy object calls the method of the target object 
		teacherDaoProxy.teach();
	}
}

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

API for generating proxy objects in JDK
1) Package of proxy class: java.lang.reflect.Proxy
2) JDK only needs to use the newProxyInstance method to implement the proxy, but the method needs to receive three parameters. The complete writing method is:
static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces,InvocationHandler h )

Improve the previous static agent to dynamic agent mode (i.e. JDK agent mode)

//Interface
public interface ITeacherDao {
	void teach(); // Training Methods
	void sayHello(String name);
}
public class TeacherDao implements ITeacherDao {

	@Override
	public void teach() {
		// TODO Auto-generated method stub
		System.out.println(" The teacher is teaching.... ");
	}

	@Override
	public void sayHello(String name) {
		// TODO Auto-generated method stub
		System.out.println("hello " + name);
	}
	
}
public class ProxyFactory {

	//Maintain a target Object
	private Object target;

	//Constructor, initializing target
	public ProxyFactory(Object target) {
		
		this.target = target;
	} 
	
	//Generate a proxy object for the target object
	public Object getProxyInstance() {
		
		//Explain
		/*
		 *  public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
                                          
            //1. ClassLoader loader :  Specifies the classloader used by the current target object. The method to get the loader is fixed
            //2. Class<?>[] interfaces: Type of interface implemented by the target object, using generic methods 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
		 */
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						System.out.println("JDK Agent begins~~");
						//Reflection mechanism calls method of target object
						Object returnVal = method.invoke(target, args);
						System.out.println("JDK Agency submission");
						return returnVal;
					}
				}); 
	}
}
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//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();
	
		// Proxy object is generated dynamically in the memory of proxyInstance=class com.sun.proxy.$Proxy0
		System.out.println("proxyInstance=" + proxyInstance.getClass());
		
		//Call the method of the target object through the proxy object
		//proxyInstance.teach();
		
		proxyInstance.sayHello(" tom ");
	}

}

The basic introduction of Cglib agent mode
1) Both the static proxy and JDK proxy patterns require that the target object is to implement an interface, but sometimes the target object is only a single object and does not implement any interface. At this time, the target object subclass can be used to implement the proxy - this is Cglib proxy
2) Cglib proxy is also called subclass proxy. It constructs a subclass object in memory to extend the function of the target object. Some books also attribute cglib proxy to dynamic proxy.
3) Cglib is a powerful and high-performance code generation package, which can extend java classes and implement java interfaces at runtime. It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception
4) How to select agent mode in AOP programming:
1. The target object needs to implement the interface with JDK agent
2. The target object does not need to implement the interface, and Cglib proxy is used
5) The bottom layer of cglib package is to transform bytecode and generate new classes by using the bytecode processing framework ASM

Cglib agent pattern implementation steps

1) The jar file of cglib needs to be introduced

2) Build subclasses dynamically in memory. Note that the class of agent cannot be final. Otherwise, an error is reported in java.lang.IllegalArgumentException

3) If the target object's method is final/static, it will not be intercepted, that is, additional business methods of the target object will not be executed

Introduction to several common agent patterns -- several variants

1) Firewall agent
The internal network through the proxy through the firewall, to achieve access to the public network.
2) Cache agent
For example, when requesting resources such as picture files, first go to the cache agent to retrieve them. If the resources are retrieved, it is ok. If the resources are not retrieved, then go to the public network or database to retrieve them, and then cache them.
3) Remote agent is the local representative of the remote object, through which the remote object can be called as a local object. The remote agent communicates information with real remote objects through the network.

4) Synchronization agent: mainly used in multithreaded programming to complete the synchronization work among multithreads

public class TeacherDao {

	public String teach() {
		System.out.println(" In the teacher's lecture, 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 a proxy object
	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 subclass object, i.e. proxy object
		return enhancer.create();
		
	}
	

	//Overriding the intercept method calls 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 ~~ Submission");
		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);
	}

}

 

103 original articles published, praised 8, visited 60000+
Private letter follow

Tags: JDK Java network Programming

Posted on Tue, 04 Feb 2020 03:05:50 -0500 by influx