Java代理

时间:2021-2-27 作者:admin

Java proxy

这只是我研究java proxy写的小例子,代码不是那么规范。
代码应该都能看懂不说明了。
一小例子

public class o {
	 public static void main(String[] args) throws Exception {
		 	face f= (face)Proxy.newProxyInstance(o.class.getClassLoader(), new Class[]{face.class}, new InvocationHandler() {
			
			face f=new imp();
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// TODO Auto-generated method stub
				System.out.println("proxy------------------");

				Object o=method.invoke(f, args[0].toString());
				return o;
			}
		});
		System.out.println(f.a("dddd"));	 	
}

interface face{
	String a(String canshu);
}

class imp implements face{

	@Override
	public String a(String canshu) {
		// TODO Auto-generated method stub
		System.out.println(canshu);
		return "imp";
	}
	
}

接下来研究一下怎么查看生成的的类信息。
进入Proxy.newProxyInstance()方法,我们只用关心生成class的方法,其他的不用看,反正我看也看不懂。

        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);

继续进入调用了ProxyClassFactory的 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) 方法里面主要的是

		   //生成字节信息
		    byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
            	//这是根据字节生成class实例
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } 

现在找到关键的代码了我们自己调一下就行

		 public static void main(String[] args) throws Exception {
		
		 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
	                "com.example.demo.proxy1", new Class[]{face.class}, 1);//类路径,class,1表示public
		 FileOutputStream fo=new FileOutputStream("C:\\Users\\Administrator.DESKTOP-3U5OF5D\\Desktop\\proxy1.class");
		 fo.write(proxyClassFile);
	 }

最后用反编译工具看一下,我用的是idea自带的


package com.example.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public class proxy1 extends Proxy implements face {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public proxy1(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String a(String var1) throws  {
        try {
            return (String)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.example.demo.face").getMethod("a", Class.forName("java.lang.String"));
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

看到生成的类继承了proxy,所以说java代理是基于接口的因为java是单继承。(还有一种cglib可以根据字节码增强)。
生成的类也没什么说的了,就是构造方法传入一个我们自己的InvocationHandler,再定义Method属性代表代理对象拥有的方法。然后调用invoke。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。