为一个对象提供一个替身,来控制这个对象的访问。通过代理对象访问目标对象,这样做的好处是可以在目标对象实现的基础上,增强额外的功能操作

被代理的对象可以是远程对象,创建开销大的对象,需要安全控制的对象

代理模式主要分为三种 静态代理,动态代理(也叫接口代理、jdk代理),cglib代理(可以在内存创建对象而不需要实现接口,属于动态代理的范畴)

静态代理

被代理类和代理类需要实现相同接口或者继承父类

12.代理模式_ide

public interface BuyHouse {
    public void housePrice();
}
public class Buyer implements BuyHouse {
    @Override
    public void housePrice() {
        System.out.println("顾客要去买房子");
    }
}
public class BuyerProxy implements BuyHouse {
    BuyHouse buyer;

    public BuyerProxy(BuyHouse buyer) {
        this.buyer = buyer;
    }

    @Override
    public void housePrice() {
        System.out.println("中介开始谈条件");
        buyer.housePrice();
        System.out.println("房子买下来签合约");
    }

    public static void main(String[] args) {
        BuyerProxy buyerProxy = new BuyerProxy(new Buyer());
        buyerProxy.housePrice();
    }
}

优点:可以动态的扩展代理类的功能而不影响到原来的被代理类的功能

缺点:两者实现同一个接口,所以一旦接口增加方法,目标类和代理类都需要维护

动态代理--动态体现在并没有把对象固定死

代理对象不需要实现接口但是被代理对象还是要实现接口,这其种是使用了jdk的api

12.代理模式_静态代理_02

public class JDKProxy {
    Object object;

    public JDKProxy(Object object) {
        this.object = object;
    }

    public Object getProxyInstance(){
        //参数说明
        //第一个参数是对象的类加载器
        //第二个对象是类对应所有的接口
        //第三个参数是即将调用目标类的方法
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("这是jdk代理买房");
                //通过反射来调用方法
                Object invoke = method.invoke(object, args);
                System.out.println("完成购房");
                //返回目标方法
                return invoke;
            }
        });
    }

    public static void main(String[] args) {
        Buyer buyer=new Buyer();
        JDKProxy jdkProxy=new JDKProxy(buyer);
        //注意这里在使用的时候要转成相应的接口
        BuyHouse proxyInstance = (BuyHouse)jdkProxy.getProxyInstance();
        proxyInstance.housePrice();

    }
}

Cglib代理(子类代理)

如果被代理类没有实现任何接口,那么我们就可以使用cglib代理

在内存种构建一个子类对象从而实现对目标对象功能扩展

需要四个包-注意版本

12.代理模式_静态代理_03

目标类

public class BuyHouse {
    public void buyHouse(){
        System.out.println("我不继承东西,但是我要买房");
    }
}

代理类

public class ProxyFactory implements MethodInterceptor {
    Object object;

    public ProxyFactory(Object object) {
        this.object = object;
    }
    //返回一个代理对象
    public Object getProxyInstance(){
        //创建一个工具类
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(object.getClass());
        //设置回调函数
        enhancer.setCallback(this);
        //返回子类对象
        return enhancer.create();
    }
    //这个方法会调用目标的方法
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理模式开始啦");
        //这里用的也是反射
        Object invoke = method.invoke(object, objects);
        System.out.println("买房结束");
        return invoke;
    }

}

12.代理模式_目标对象_04

 

 12.代理模式_代理类_05