jdk动态代理学习

在jdk的好多底层代码中很多都使用jdk的动态代理,下面就写写简单的代码来look look.

老规矩先上代码:

public interface SayDao {
    public String sayChinese();
    public String sayEnglish();
}
View Code
public class SayDaoImpl implements SayDao {
    @Override
    public String sayChinese() {

        return "我就是我!";
    }

    @Override
    public String sayEnglish() {
        return "I am tom_plus!";
    }
}
View Code
public class JDBCProxy implements InvocationHandler {
    private Object target;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke begin!");
        return method.invoke(target,args);
    }
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
}
View Code
public class JDBCProxyTest {
    public static void main(String[] args) {
        JDBCProxy jdbcProxy = new JDBCProxy();
        SayDao sayDao = (SayDao) jdbcProxy.bind(new SayDaoImpl());
        String s = sayDao.sayChinese();
        System.out.println(s);
        System.out.println("----------------");
        printClassDefinition(sayDao.getClass());
    }
    public static String getModifier(int modifier) {
        String result = "";
        switch(modifier){
            case Modifier.PRIVATE:
                result = "private";
            case Modifier.PUBLIC:
                result = "public";
            case Modifier.PROTECTED:
                result = "protected";
            case Modifier.ABSTRACT :
                result = "abstract";
            case Modifier.FINAL :
                result = "final";
            case Modifier.NATIVE :
                result = "native";
            case Modifier.STATIC :
                result = "static";
            case Modifier.SYNCHRONIZED :
                result = "synchronized";
            case Modifier.STRICT  :
                result = "strict";
            case Modifier.TRANSIENT :
                result = "transient";
            case Modifier.VOLATILE :
                result = "volatile";
            case Modifier.INTERFACE :
                result = "interface";
        }
        return result;
    }

    public static void printClassDefinition(Class clz){

        String clzModifier = getModifier(clz.getModifiers());
        if(clzModifier!=null && !clzModifier.equals("")){
            clzModifier = clzModifier + " ";
        }
        String superClz = clz.getSuperclass().getName();
        if(superClz!=null && !superClz.equals("")){
            superClz = "extends " + superClz;
        }

        Class[] interfaces = clz.getInterfaces();

        String inters = "";
        for(int i=0; i<interfaces.length; i++){
            if(i==0){
                inters += "implements ";
            }
            inters += interfaces[i].getName();
        }

        System.out.println(clzModifier +clz.getName()+" " + superClz +" " + inters );
        System.out.println("{");

        Field[] fields = clz.getDeclaredFields();
        for(int i=0; i<fields.length; i++){
            String modifier = getModifier(fields[i].getModifiers());
            if(modifier!=null && !modifier.equals("")){
                modifier = modifier + " ";
            }
            String fieldName = fields[i].getName();
            String fieldType = fields[i].getType().getName();
            System.out.println("    "+modifier + fieldType + " "+ fieldName + ";");
        }

        System.out.println();

        Method[] methods = clz.getDeclaredMethods();
        for(int i=0; i<methods.length; i++){
            Method method = methods[i];

            String modifier = getModifier(method.getModifiers());
            if(modifier!=null && !modifier.equals("")){
                modifier = modifier + " ";
            }

            String methodName = method.getName();

            Class returnClz = method.getReturnType();
            String retrunType = returnClz.getName();

            Class[] clzs = method.getParameterTypes();
            String paraList = "(";
            for(int j=0; j<clzs.length; j++){
                paraList += clzs[j].getName();
                if(j != clzs.length -1 ){
                    paraList += ", ";
                }
            }
            paraList += ")";

            clzs = method.getExceptionTypes();
            String exceptions = "";
            for(int j=0; j<clzs.length; j++){
                if(j==0){
                    exceptions += "throws ";
                }

                exceptions += clzs[j].getName();

                if(j != clzs.length -1 ){
                    exceptions += ", ";
                }
            }
            exceptions += ";";
            String methodPrototype = modifier +retrunType+" "+methodName+paraList+exceptions;
            System.out.println("    "+methodPrototype );
        }
        System.out.println("}");
    }

}
View Code

我的视角:

动态代理其实就是Proxy类动态的根据指定的所有接口生成一个class,该class会继承Proxy类,并实现所有指定的接口(在参数中传入的接口数组);然后再利用指定的classloader将 class加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现所有的接口的Proxy对象。

从代码角度:

com.sun.proxy.$Proxy0 extends java.lang.reflect.Proxy implements com.springapp.test.SayDao
{
java.lang.reflect.Method m1;
java.lang.reflect.Method m0;
java.lang.reflect.Method m3;
java.lang.reflect.Method m4;
java.lang.reflect.Method m2;

boolean equals(java.lang.Object);
java.lang.String toString();
int hashCode();
java.lang.String sayChinese();
java.lang.String sayEnglish();
}

具体细节:

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
参数一:类加载器,把创建的代理类class加载进系统。
参数二:被代理对象实现的接口 class数组
参数三:调度处理程序类,内有invoke()方法,代理的核心就是调InvocationHandler类的invoke(Object proxy, Method method, Object[] args)方法
,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
注意点:Object proxy 这个参数,代表的是代理类对象。
调用这个方法,返回代理类 class。
原文地址:https://www.cnblogs.com/tom-plus/p/5586757.html