Java proxy mode is simple to organize

Posted by AdamSnow on Fri, 21 Jun 2019 18:55:07 +0200

Previously, I learned the proxy mode of Java, and I was deeply impressed by how wonderful this mode is!A simple tidy up for later viewing.

Definition: Provides a proxy for other objects to control access to this object.(e.g. train ticket agent point)

Classification:

Remote Agent
Virtual Agent
Protection Agent
Smart Reference Agent

Smart Reference Agent

Static Proxy
The proxy and the proxy object are determined before they are proxied.They all implement the same interface or inherit the same abstract class.

Two implementations: inheritance (not recommended) and aggregation
Dynamic Proxy

jdk dynamic proxy

1. Only classes that implement interfaces can be proxied
2. Classes that do not implement interfaces cannot implement jdk's dynamic proxy.

CGLIB Dynamic Proxy

1. Implementing proxy against classes
2. Produce a subclass of the specified target class, intercepting all calls to parent methods through method interception techniques

jdk dynamic proxy

Key: ProxyHandler Transaction Processor

Steps to achieve:

1. Create a class that implements the interface InvocationHandler, which must implement the invoke method
2. Create proxied classes and interfaces
3. Call Proxy's static method to create a proxy class
newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
4. Call methods through proxy

Sample Code: (Simulate Time Recording and Logging Dynamic Agent, Simple and Clear)

package com.jdkproxy;
/**
 * Interface implemented by proxy class
 * @author Administrator
 */
public interface Moveable {
	public void move();
}
package com.jdkproxy;

import java.util.Random;
/**
 * Proxy Class
 * @author Administrator
 */
public class Car implements Moveable {
	@Override
	public void move() {
		// Realize driving
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println("The car is running.");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * Pattern Implementation Log Logging Agent Class
 * @author Administrator
 */
public class LogProxy implements InvocationHandler {
	private Object target;
	public LogProxy(Object target) {
		super();
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("Logging Start");
		method.invoke(target);
		System.out.println("Logging End");
		return null;
	}

}
package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Schema implementation Time record proxy class
 * @author Administrator
 *
 */
public class TimeHandler implements InvocationHandler {
	
	private Object target;
	public TimeHandler(Object target) {
		super();
		this.target = target;
	}
	
	/**
	 * Parameters:
	 * proxy: Proxy Object
	 * method: Method of Proxy Object
	 * args: Parameters of the method
	 * 
	 * Return value
	 * Object Return value of method
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		long starttime = System.currentTimeMillis();
		System.out.println("The car is starting to run.");
		method.invoke(target);
		long endtime = System.currentTimeMillis();
		System.out.println("The car is over.Car travel time" + (endtime - starttime) + "Millisecond");
		return null;
	}

}
package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import com.proxy.Car;
import com.proxy.Moveable;

/**
 * jdk Dynamic Proxy Test Class
 * @author Administrator
 *
 */
public class Test {
	public static void main(String[] args) {
		Car car = new Car();
		InvocationHandler h = new TimeHandler(car);
		
		Class<?> cls = car.getClass();
		/**
		 * loader classloader
		 * interfaces Implement Interface
		 * h InvocationHandler
		 */
		//Add Time Agent
		Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
		//Add Log Agent
		InvocationHandler h1 = new LogProxy(m);
		Moveable m2 = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h1);
		m2.move();
	}
}
CGLIB Dynamic Proxy

Produces a subclass of the specified target class and intercepts calls to all parent methods through method interception techniques.

Code example:

package com.cglib;

public class Train {
	
	public void move(){
		System.out.println("The train is running.");
	}
}
package com.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {
	
	private Enhancer enhancer = new Enhancer();
	
	public Object getProxy(Class clazz){
		//Set the class for which the subclass is created (for which class the proxy class is generated)
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		
		return enhancer.create();
	}
	
	/**
	 * Intercept calls to all target class methods
	 * Parameters:
	 * obj Instances of the target class
	 * m Reflected object of target method
	 * args Parameters of the method
	 * proxy Instances of proxy classes
	 */
	@Override
	public Object intercept(Object obj, Method m, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("Log Start");
		//Proxy class calls parent class's methods
		proxy.invokeSuper(obj, args);
		System.out.println("Log End");
		return null;
	}

}
package com.cglib;

public class Client {
	
	public static void main(String[] args) {
		CglibProxy proxy = new CglibProxy();
		Train t = (Train) proxy.getProxy(Train.class);
		
		t.move();
	}
}
Simulate the implementation of the JDK dynamic proxy and record it later.

Topics: Java JDK