设计模式--代理模式

代理模式是指为其他对象提供一种代理,以控制对这个对象的访问。在客户端和莫表对象之前起一个中介的作用。作用呢就是保护和增强目标对象(AOP)。
静态代理是指通过手动代理的方式完成代理,被代理的类增加方法,代理类也需要增加方法,很明显违背了开闭原则。而动态代理则是在运行时生成代码,取消了对类的扩展限制,符合开闭原则。

  • 静态代理
    就好比租房。
    有这样一个房子接口:
public interface Room{
    //租房子
    void findRoom();
}

一个刚毕业的大学生要租房子:

public class Stdent implements Room{
    //租房子
    public void findRoom(){
        System.out.println("想要一个带阳台的房子");
    }
}

这个时候他去中介租房子

public class Angency{
    private Object obj;
    
    public Angency(Object obj){
        this.obj=obj;
    }
    
    public void findRoom(){
        beforeFindRoom();
        obj.findRoom();
        afterFindRoom();
    }
    
    private void beforeFindRoom(){
        System.out.println("中介带你看房子");
    }
    
    private void afterFindRoom(){
       System.out.println("交钱!");
    }
}

可以写个测试方法测试一下:

Angency an=new Angency(new Stdent ());
an.findRoom();
  • 动态代理
    动态代理有两种形式,jdk与cglib。

(1)jdk
同样是中介,利用反射去实现代理,这样实现呢,简单,但是效率低,毕竟空间和时间不可兼得嘛。

public class Angency implements InvocationHandler {
	private Object obj;

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

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		beforeFindRoom();
		Object obj = method.invoke(this.obj, args);
		afterFindRoom();
		return obj;
	}

	private void beforeFindRoom() {
		System.out.println("中介带你看房子");
	}

	private void afterFindRoom() {
		System.out.println("交钱!");
	}
}

原理呢就是:先拿到被代理对象的引用,通过反射获取到他的接口,然后、JDK Proxy 类去生成一个实现所有接口的新类,动态生成代码,最后再编译执行。
(2)cglib

public class Angency implements MethodInterceptor {
	public Object getInstance(Class<?> clazz) throws Exception {
		Enhancer enhancer = new Enhancer();
		// 要把哪个设置为即将生成的新类父类
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}

	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
		befbeforeFindRoomore();
		Object obj = methodProxy.invokeSuper(o, objects);
		afterFindRoom();
		return obj;
	}

	private void beforeFindRoom() {
		System.out.println("中介带你看房子");
	}

	private void afterFindRoom() {
		System.out.println("交钱!");
	}
}

Cglib 是通过动态继承目标对象实现的动态代理,使用 ASM 框架写 Class 字节码,实现更复杂,生成代理类效率低。而JDK Proxy 则是实现了被代理对象的接口,通过反射机制调用。二者都是在运行期生成代码的。
个人理解:代理模式将代理对象与调用的目标对象分离,降低了系统耦合性,可以保护增强目标对象,扩展性较好。但是代理模式增加了代码,代码一多,就降低理解性,代理对象与调用的目标对象分离,多走了一步,后台响应速度肯定会变慢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值