Proxy代理模式

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(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技梦想家

创作不易,欢迎施舍

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值