• java代理的学习,通过类实现接口来实现代理。proxy来创建动态类,和InvocationHandler接口的实现,和工作原理。


    1、java自带的proxy类可以创建动态类,如果一个类实现了一个接口那么久可以为这个类创建代理。

    2、代理:就是当用户要调用一个类的方法时,用户可以通过调用代理,代理通过接口调用原来的类的方法,代理在把方法给用户前可以添加一些方法,如错误日志,用户类的方法运行的时间来监听类方法的性能。当代理完成时候就是当代理调用方法时候,就会启动InvocationHandler里的invoke方法。用户并不知道用户要为哪个类带理,因此在框架中用配置文件来获取代理的类,用户需要用框架时候就修改配置文件即可。

    public class Proxydemo {
    
    	public static void main(String[] args) throws Exception {
    
    		//这是分2部,来实现collection的代理的,下面是1步实现代理,并且是任何类
    //		Class classproxy=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
    //		 Constructor[]constructors=classproxy.getConstructors();
    //		 Constructor constructor=classproxy.getConstructor(java.lang.reflect.InvocationHandler.class);
    //		 for(Constructor c:constructors)
    //		 {
    //			 System.out.println(c.toString());
    //		 }
    ////		final ArrayList a=new ArrayList<>();
    //		Collection  c=(Collection) constructors[0].newInstance(new InvocationHandler(){
    //
    //			@Override
    //			public Object invoke(Object proxy, Method method, Object[] args)
    //					throws Throwable {
    //				ArrayList a=new ArrayList<>();
    //				System.out.println(System.currentTimeMillis());
    //				Object ob=method.invoke(a ,args);
    //				System.out.println("a的size:"+a.size());
    //				System.out.println(System.currentTimeMillis());
    //				return ob;
    //			}
    //			 
    //		 });
    ////		c.add("dada"); c.add("dada");
    ////		System.out.println( c.size());
    //		 
    		//下面是实现代理的原理,pr是给代理的接口,advice是代理要监控方法的接口
    		final Pro pr=new ProtexTest();
    		final Advice advice=new MyAdvice();
    		Pro classproxy=(Pro)Proxy.newProxyInstance(pr.getClass().getClassLoader(), new Class[]{Pro.class}, new  InvocationHandler(){
    			@Override
    			public Object invoke(Object proxy, Method method, Object[] args)
    					throws Throwable {
    				advice.beforemethod();//这是方法前调用的方法
    				Object o=method.invoke(pr, args);
    				advice.aftermethod();//这是方法后调用的方法
    				return o;
    			}
    		});
    //当调用sayhello时候,系统就去找代理调用InvocationHandler里的invoke方法。
         classproxy.sayhello();
    /*		所以打印结果为:
    		1441522392491
    		hello
    		1441522392493
    */		
         
        //调用代理函数
         Pro o=(Pro) daili(pr,advice);
         o.sayhello();
         
    	}
    	/******************下面可以吧上面的方法抽出为一个代理方法,为任何实现接口的类代理*****/
    	/*
    	 * target 为目标类实现的接口
    	 * advice为代理要监控方法的接口
    	 */
    	public static Object daili(final Object target,final Advice advice)
         {
    		Object classproxy=(Object)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new  InvocationHandler(){
    			@Override
    			public Object invoke(Object proxy, Method method, Object[] args)
    					throws Throwable {
    				advice.beforemethod();//这是方法前调用的方法
    				Object o=method.invoke(target, args);
    				advice.aftermethod();//这是方法后调用的方法
    				return o;//返回方法执行后返回的值
    			}
    		});
    		return classproxy;
         }
    }
    

      

  • 相关阅读:
    VB.net byval和byref
    IOS 常用宏定义(二)
    目录权限Linux存储实验四:NFS的安装与配置
    服务器负载均衡nginx+keepalived 高可用负载均衡
    博客文件第二部分 Linux Shell高级编程技巧——第一章 深入讨论
    查看进程第二部分 Linux Shell高级编程技巧——第二章 Shell工具
    响应命令使用Ubuntu架设ftp服务器
    进程内存Linux下top命令
    客户端服务器SSH原理和使用
    安装数据空间虚拟CentOS访问Windows下共享文件
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/4786308.html
Copyright © 2020-2023  润新知