JDK的动态代理

首先建立一个接口类

public interface Person {
    void study();
}

并实现接口

@Component
public class Teacher implements Person {
    public Teacher() {
    }

    @Override
    public void study() {
        System.out.println("老师正在学习钢琴");
    }
}

创建实现Invocation的类,在这个类中实现增强代理类的方法

public class TestInvocation implements InvocationHandler{


    private  Object object;

    public TestInvocation(Object object)
    {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("吃完早餐准备学习了");
        method.invoke(object,args);
        System.out.println("开始健身了");
        return null;
    }
}

创建main方法开始测试


public static void main(String[] args) {
//创建需要代理的类
Person teacher= new Teacher();
// 创建实现Invocation的对象将需要代理的类关联起来
TestInvocation invocation = new TestInvocation(teacher);
//jdk中通过proxynewProxyInstance方法来创建代理类对象
//第一个参数使用invocationclassLoader来加载代理类的对象
//第二个参数获取代理类所实现的接口
//第三个参数将代理类和实现Invcation的接口的类关联起来
Person teacher1 = (Person)Proxy.newProxyInstance(invocation.getClass().getClassLoader(), teacher.getClass().getInterfaces(), invocation);
System.out.println(teacher1.getClass().getName());
teacher1.study();
}

打印出的结果

com.sun.proxy.$Proxy0
吃完早餐准备学习了
老师正在学习钢琴
开始健身了

system.out.println(teacher1.getClass().getName());
打印出的是com.sun.proxy.$Proxy0
 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
//首先判断实现invocation的类是否为空
        Objects.requireNonNull(h);
//    复制接口对象
        final Class<?>[] intfs = interfaces.clone();
//    获取一个安全管理对象
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
  //    生成代理类对象此时的对象就为(com.sun.proxy.$Proxy0)
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
//返回Class对象所表示的类的指定公共一个构造对象
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
//    进行反射查看代理类的修饰符
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
//    通过反射创建新对象
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }    

反射创建的对象为jvm运行的时候创建的一个动态的对象同时转换成

 Person teacher1 = (Person)Proxy.newProxyInstance(invocation.getClass().getClassLoader(), teacher.getClass().getInterfaces(), invocation);
调用teeacher的方法完成
posted @ 2018-08-22 18:26  TracyRanch  阅读(135)  评论(0编辑  收藏  举报