设计模式——代理模式之静态代理和动态代理

代理模式:官方定义,为其他对象提供一个代理以控制对这个对象的访问。形象的说,代理模式就是提供一个代理对象,这个对象有被代理对象的相同的功能,实际上代理对象的功能实现也是通过调用被代理对象的方法实现的。
像c++中的指针对象,Java中的引用对象,也可以看做是一个代理对象,他们代理了所指向和引用的对象。现实中的中介、黄牛也是代理对象,他们是甲方、售票处的代理对象。

静态代理

一个简单的静态代理的例子

一个接口


public interface Mouse {

    public void eat();

}

被代理类

public class Jack implements Mouse {
    public void eat() {
        System.out.println("老鼠吃东西。");
    }
}

代理类

public class StatictProxy {

	//保存代理对象
    private Mouse mouse;

    public StatictProxy(Mouse mouse){
        this.mouse = mouse;
    }

    public void eat(){
    	//执行方法前可以做一些事情
        System.out.println("开始代理。。。");
        mouse.eat();
        //执行方法后可以做一些事情
    }
}

缺点:不易扩展,耦合高

动态代理

通过字节码重组生成一个与被代理对象实现相同接口,并且通过一个指定的handler来调度的代理对象。

  • JDK的动态代理
    JDK代理依赖于java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy这两类。
    Proxy是用于生成代理对象,而InvocationHandler则是代理对象执行方法是由其invoke方法来实现的。

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

public class JDKProxy<T> implements InvocationHandler {
	//被代理对象
    private T t;
    
    //获取代理对象
    public  T getInstance(T t){
        this.t = t;
        //获取被代理的类
        Class<? > targetClass = t.getClass();
		//通过Proxy的newProxyInstance获取代理对象
        return (T)Proxy.newProxyInstance(targetClass.getClassLoader(), targetClass.getInterfaces(), this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行代理");
        method.invoke(this.t,args);
        return null ;
    }
}

测试

 public static void main(String[] args) {
        Object instance = new JDKProxy().getInstance(new Jack());
        Mouse mouse = (Mouse) instance;
        mouse.eat();

    }
  • cglib动态代理

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

import java.lang.reflect.Method;

public class CglibProxy<T> implements MethodInterceptor {

    public T getProxyInstance(Class clazz){
    	//生成一个代理类
        Enhancer enhancer = new Enhancer();
        //设置代理类的父类
        enhancer.setSuperclass(clazz);
        //设置方法调用
        enhancer.setCallback(this);

        return (T) enhancer.create();
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("start proxy");
        methodProxy.invokeSuper(o, objects);
        return null;
    }
}

优势:被代理类可以不用实现接口

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值