zoukankan      html  css  js  c++  java
  • 代理与动态代理 阅读think in java所得(2)

    代理是基本的设计模式之一,是你为了提供额外的或者不同的操作,而插入的用来代替“实际”对象的对象。

    ProxyDemo.java:

    import java.lang.reflect.Proxy;
    
    interface Animal{
    	void eat();
    }
    
    class Dog implements Animal{
    
    	public void eat() {
    		System.out.println( "Dog's eat...." );
    	}
    	
    }
    
    class ProxyClient implements Animal{
    	private Animal animalProxy;
    	
    	ProxyClient( Animal animal ){
    		animalProxy = animal;
    	}
    	
    	public void eat() {
    		System.out.println( "animal wash hands first...." );
    		animalProxy.eat();
    	}
    }
    
    public class ProxyDemo {
         public static void consumer( Animal animal ){
           animal.eat
         }
    
    	public static void main( String[] args ){
          consumer( new ProxyClient( new Dog() ) )
    
         }
     }
    

      

      动态代理:可以动态的创建代理,并动态的处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。

    下面DynamicProxyDemo.java用动态代理重写ProxyDemo.java

    View Code
    interface Animal{
        void eat();
    }
    
    class Dog implements Animal{
    
        public void eat() {
            System.out.println( "Dog's eat...." );
        }
        
    }
    class DynamicProxyHandler implements InvocationHandler{
        private Object proxied;
    
        DynamicProxyHandler( Object proxied ){
            this.proxied = proxied;
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println( "proxy:"+proxy.getClass()+" ,method: "+method+" ,args: "+args );
            if( args != null){
                for( Object arg : args ){
                    System.out.println(" "+arg);
                }
            }
            return method.invoke( proxied, args );
        }
        
    }
    public class DynamicProxyDemo {
        public static void consumer( Animal animal ){
            animal.eat();
        }
        public static void main( String[] args ){
            
            Animal proxy = ( Animal )Proxy.newProxyInstance( Animal.class.getClassLoader() ,  new Class[]{ Animal.class },  new DynamicProxyHandler( new Dog() ));
            consumer(proxy);
        }
    }

    通过调用静态方法Proxy.newProxyInstance()可以创建动态代理,这个方法需要一个类加载器,一个你希望该代理实现的接口列表,以及一个InvocationHandler接口的实现。

    invoke()中传递进来了代理对象,以防你需要区分请求的来源,在其内部,在代理上调用方法时要格外当心,因为对接口的调用会被重定向为对代理的调用。

    通常,你会执行被代理的操作,然后使用Method.invoke()将请求转发给被代理对象,并传入必须的参数。但是你可以通过传递其他的参数,来过滤某些方法调用。代码如下:

    class MethodSelector implements InvocationHandler{
    
    	private Object proxied;
    	
    	public MethodSelector( Object proxied ){
    		this.proxied = proxied ;
    	}
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		if( method.getName().equals( "eat" ) ){
    			System.out.println( "proxy detected the interesting method" );
    		}
    		return method.invoke( proxied , args);
    	}
    	
    }
    

      

  • 相关阅读:
    一种新的数据类型Symbol
    var/let/const的区别
    Vue-cli脚手架 安装 并创建项目--命令
    命令
    git版本控制入门--码云
    闲鱼hu超赞,有赞必回,24小时在线!咸鱼互赞超赞留言评
    咸鱼互粉互赞必回 有没有宝贝要的_咸鱼吧
    闲鱼互赞群
    拍摄者能在抖音教学中学会什么
    影响抖音推荐机制的因素和上热门
  • 原文地址:https://www.cnblogs.com/nextStep/p/2565490.html
Copyright © 2011-2022 走看看