Design pattern series -- agent pattern

Definition

Proxy mode refers to providing a proxy for other objects to control access to this object. The proxy object mediates between the client and the target object.

According to the type of the object being proxied, the proxy mode is divided into static proxy and dynamic proxy. Static agents can only specify types, while dynamic agents do not limit types.

Static agent

Define interface Person

public interface Person {

	void findHouse();

}

Agent object Renter

public class Renter implements Person {

	[@Override](https://my.oschina.net/u/1162528)
	public void findHouse() {
		System.out.println("Three rooms and two halls");
		System.out.println("Convenient traffic");
	}

}

Proxy object AgencyStaticProxy, enhanced part doBefore(),doAfter()

public class AgencyStaticProxy  {

	private Person person;

	public AgencyStaticProxy(Person person) {
		this.person = person;
	}

	public void findHouse() {
		doBefore();
		person.findHouse();
		doAfter();
	}

	void doBefore() {
		System.out.println("Please describe the house requirements: static agent");
	}

	void doAfter() {
		System.out.println("Transaction completed, please pay the intermediary fee of 2000 yuan");
	}

}

Test class

public class Test {

	public static void main(String[] args) {
		AgencyStaticProxy agency = new AgencyStaticProxy(new Renter());
		agency.findHouse();
	}
}

Dynamic agent

1. JDK dynamic agent

Proxy object, AgencyJdkProxy, implements the InvocationHandler interface

public class AgencyJdkProxy implements InvocationHandler {

	private Object object;

	public Object getInstance(Object target) {
		this.object = target;
		Class<?> clazz = object.getClass();
		Object o = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
		return o;
	}

	[@Override](https://my.oschina.net/u/1162528)
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		doBefore();
		Object invoke = method.invoke(this.object, args);
		doAfter();
		return invoke;
	}

	void doBefore() {
		System.out.println("Please describe the needs of the house: JDK Dynamic agent");
	}

	void doAfter() {
		System.out.println("Transaction completed, please pay the intermediary fee of 2000 yuan");
	}

}

Test class

public class Test {

	public static void main(String[] args) {
		Renter renter = new Renter();
		Person person = (Person) new AgencyJdkProxy().getInstance(renter);
		person.findHouse();
	}
}

The proxy object of JDK dynamic proxy must implement the interface.

2. Cglib dynamic agent

Surrogate object RenterOnly

public class RenterOnly {
	public void findHouse() {
		System.out.println("Three rooms and two halls");
		System.out.println("Convenient traffic");
	}
}

Proxy object AgencyCglibProxy

public class AgencyCglibProxy implements MethodInterceptor {

	public Object getInstance(Class<?> clazz) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}

	[@Override](https://my.oschina.net/u/1162528)
	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
		doBefore();
		Object invokeSuper = methodProxy.invokeSuper(o, objects);
		doAfter();
		return invokeSuper ;
	}

	void doBefore() {
		System.out.println("Please describe the needs of the house: Cglib Dynamic agent");
	}

	void doAfter() {
		System.out.println("Transaction completed, please pay the intermediary fee of 2000 yuan");
	}
}

Test class

public class Test {

	public static void main(String[] args) {
		RenterOnly renterOnly = (RenterOnly)new AgencyCglibProxy().getInstance(RenterOnly.class);
		renterOnly.findHouse();
	}
}

1. JDK dynamic proxy implements the interface of the proxy object, Cglib inherits the proxy object.

2. Both JDK dynamic agent and cglib dynamic agent generate bytecode at runtime. JDK writes Class bytecode directly. Cglib uses ASM framework to write Class bytecode. Cglib agent implementation is more complex, and the generation agent is inefficient compared with JDK.

3. JDK calls the proxy method through reflection mechanism, Cglib directly calls the method through FastClass mechanism, and Cglib is more efficient.

4. Cglib can't represent final decorated methods

Tags: Programming JDK

Posted on Tue, 05 May 2020 19:22:47 -0400 by macattack