设计模式系列--代理模式

定义

代理模式是指为其他对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。

根据被代理对象的类型,代理模式分为静态代理和动态代理。静态代理只可以代理指定类型,动态代理不限制类型。

静态代理

定义接口 Person

public interface Person {

	void findHouse();

}

被代理对象 Renter

public class Renter implements Person {

	@Override
	public void findHouse() {
		System.out.println("三室两厅");
		System.out.println("交通方便");
	}

}

代理对象 AgencyStaticProxy,增强部位 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("请描述房子需求:静态代理");
	}

	void doAfter() {
		System.out.println("已成交,请支付中介费用2000元");
	}

}

测试类

public class Test {

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

设计模式系列--代理模式_第1张图片

动态代理

1、JDK动态代理

代理对象 AgencyJdkProxy ,实现InvocationHandler 接口

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
	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("请描述房子需求:JDK动态代理");
	}

	void doAfter() {
		System.out.println("已成交,请支付中介费用2000元");
	}

}

测试类

public class Test {

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

设计模式系列--代理模式_第2张图片

JDK动态代理的被代理对象必须实现 接口。

2、Cglib动态代理

被代理对象 RenterOnly

public class RenterOnly {
	public void findHouse() {
		System.out.println("三室两厅");
		System.out.println("交通方便");
	}
}

代理对象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
	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("请描述房子需求:Cglib动态代理");
	}

	void doAfter() {
		System.out.println("已成交,请支付中介费用2000元");
	}
}

测试类

public class Test {

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

设计模式系列--代理模式_第3张图片

1、JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。

2、JDK动态代理和Cglib动态代理都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。

3、JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

4、Cglib无法代理 final修饰的方法

你可能感兴趣的:(设计模式,设计模式,java,反射,proxy)