美文网首页
代理模式

代理模式

作者: 回眸婉约 | 来源:发表于2020-04-16 14:51 被阅读0次

    主要是解决直接访问对象的问题,如果直接访问对象可能会给系统结构带来很多问题

    开放封闭原则(OCP,Open Closed Principle)软件实体应该是可扩展,而不可修改的。也就是说,一个软件实体应当对扩展是开放的,而对修改是封闭的。

    1.静态代理

    定义接口

            public interface Animal {
               void eat();
            }
    

    定义两个类被代理的类

            public class Panda implements Animal {
               @Override
               public void eat() {
                  System.out.println("吃竹子");
               }
            }
    
            public class Tiger implements Animal {
               @Override
               public void eat() {
                  System.out.println("吃肉");
               }
            }
    

    调用代理类

            public class Demo {
               public static void main(String[] args) {
                  Animal animal = new Tiger();
                  animal.eat(); 
               }
            }  
    

    这样接口就可以按照使用场景进行划分,问题也出现了,这个代理只能为一个类服务,多个就要写很多代理类

    这里有点像java中的多态 多态存在的三个必要条件1继承2重写3父类引用指向子类对象。3父类引用指向子类,忙猜多态是针对对象的,而代理是针对接口的

    2.动态代理

    对象的执行方法,交给代理来负责。比如user.get() 方法,是User对象亲自去执行。而使用代理则是由proxy去执行get方法。

    InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口每一个proxy代理实例都有一个关联的调用处理程序,成对出现

             public class DynamicHandler implements InvocationHandler {
    
                Object animal;
            
                public DynamicHandler(Object animal) {
                    this.animal = animal;
                }
            
                /**
                * proxy:代理类代理的真实代理对象 
                * method:我们所要调用某个对象真实的方法的Method对象
                * args:指代代理对象方法传递的参数
                */        
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    method.invoke(animal, args);
                    return null;
                }
            }
    

    Proxy类就是用来创建一个代理对象的类

             public class Demo {
               public static void main(String[] args) {
                    Animal animal = new Panda();
                    InvocationHandler handler = new DynamicHandler(animal);
                    Animal proxyHello = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), handler);
                    //Animal proxyHello = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), new Class<?>[]{Animal.class}, handler);                
                    proxyHello.eat();        
               }
            }  
    

    loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载

    interfaces:一个interface对象数组,表示我们要提供给代理对象 一组 接口, 代理类就可以调用接口中声明的所有方法。

    h: 一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用

    可以在method.invoke(animal, args); 方法前后做一些控制。
    有名的Retorfit 就是由动态代理做的点开 retrofit.create 就能看到 Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },new InvocationHandler() {});

    如果内容有错误请及时联系我

    相关文章

      网友评论

          本文标题:代理模式

          本文链接:https://www.haomeiwen.com/subject/rcirvhtx.html