侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130555 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

[设计模式]Proxy代理模式

2023-09-22 星期五 / 0 评论 / 0 点赞 / 25 阅读 / 7198 字

1.定义 给某个对象提供一个代理对象,由代理对象控制对原对象的引用。 区别: 1.适配器模式:适配器模式改变对象的接口,代理模式不改变接口。 2.装饰器模式:装饰者模式是为了增加功能,代理模式是为了控

1.定义

给某个对象提供一个代理对象,由代理对象控制对原对象的引用。

区别:

1.适配器模式:适配器模式改变对象的接口,代理模式不改变接口。

2.装饰器模式:装饰者模式是为了增加功能,代理模式是为了控制。

2.使用场景

1.中介隔离:隔离访问,原对象不能被直接引用时,代理对象可以通过实现相同的接口来间接提供给客户访问。

2.功能增强:扩展原对象的功能。主要负责预处理,过滤,事后对返回结果的处理。比如日志功能,解决乱码问题。

3.使用方法

按代理创建的时期,分为静态代理,动态代理。

静态代理是在源码上创建,并对其编译。

动态代理是在程序运行时,通过反射机制动态创建。

注意:代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理

3.1 静态代理

1.创建服务接口

public interface Machine {    void run();}

2.创建原对象

public class RealMachine implements Machine {    private String machineName;    public RealMachine(String machineName){        this.machineName = machineName;        init();    }    @Override    public void run() {        System.out.println("run " + machineName);    }    private void init(){        System.out.println("init "+machineName);    }}

3.创建代理对象

public class ProxyMachine implements Machine{    private RealMachine realMachine;    private String machineName;    public ProxyMachine(String machineName){        this.machineName = machineName;    }    @Override    public void run() {        if(realMachine == null){            realMachine = new RealMachine(machineName);        }        System.out.println("start run");        realMachine.run();        System.out.println("stop run");    }}

4.测试

    @Test    public void testStaticMachine(){        Machine machine = new ProxyMachine("robot 001");        machine.run();    }

静态代理总结

每一个原对象都要创建一个代理类,不适合

3.2 动态代理

1.创建动态代理类

public class DynamicProxyHandler implements InvocationHandler{    private Object object;    public DynamicProxyHandler(final Object object){        this.object = object;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("start proxy run");        Object invoke = method.invoke(object, args);        System.out.println("stop proxy run");        return invoke;    }}

2.测试

    @Test    public void testDynamicMachine(){        Machine machine = new RealMachine("robot 002");        Machine proxyMachine = (Machine) Proxy.newProxyInstance(                Machine.class.getClassLoader(), new Class[]{Machine.class}, new DynamicProxyHandler(machine));        proxyMachine.run();    }

动态代理总结

代理包:java.lang.reflect.Proxy

JDK动态代理需要使用newProxyInstance方法.

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

三个参数:

1.ClassLoader loader: 指定当前目标对象使用类加载器,获取加载器的方法是固定的

2.Class<?>[] interfaces: 目标对象实现的接口的类型,使用泛型方式确认类型

3.InvocationHandler h 事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入

3.3 代理工厂

1.创建代理工厂

public class ProxyFactory {    private Object object;    public ProxyFactory(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("start proxyFactory");                        Object invoke = method.invoke(object, args);                        System.out.println("stop proxyFactory");                        return invoke;                    }                }        );    }}

2.测试

    @Test    public void testProxyFactory(){        Machine machine = new RealMachine("robot 003");        Machine proxyInstance = (Machine) new ProxyFactory(machine).getProxyInstance();        proxyInstance.printMessage("test");    }

3.4 cglib代理工厂

和JDK代理不同,当目标对象没有实现任何接口时,cglib代理可以对目标对象进行代理。

cglib代理,又名子类代理。它是在内存中构建一个子类对象,从而实现对目标对象功能的扩展。

1.依赖包

asm-2.2.3,asm-commons-2.2.3,asm-util-2.2.3 ,cglib-nodep-2.1_3

2.创建实体

public class CglibMachine{    private RealMachine realMachine;    private String machineName;    public CglibMachine(){    }    public CglibMachine(String machineName){        this.machineName = machineName;    }    public void run() {        if(realMachine == null){            realMachine = new RealMachine(machineName);        }        System.out.println("start run");        realMachine.run();        System.out.println("stop run");    }}

3.创建工厂

public class CglibProxyFactory implements MethodInterceptor{    private Object object;    public CglibProxyFactory(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 target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        System.out.println("start cglib proxy");        //执行目标对象方法        Object invoke = method.invoke(object, args);        System.out.println("stop cglib proxy");        return invoke;    }}

4.测试

    @Test    public void testCglibFactory(){        CglibMachine machine = new CglibMachine("robot 004");        CglibMachine proxyInstance = (CglibMachine) new CglibProxyFactory(machine).getProxyInstance();        proxyInstance.run();    }

广告 广告

评论区