为了账号安全,请及时绑定邮箱和手机立即绑定

请教请教,路过的也看一看,帮一帮我,出点主意

请教请教,路过的也看一看,帮一帮我,出点主意

有一种放弃叫三分热情 2017-09-08 12:05:40
关于动态代理的那些事 (JDK的动态代理)有3个接口,分别为ProxyInter1,ProxyInter2,ProxyInter3,但是接口2继承接口3public interface ProxyInter1{ void func(); }public interface ProxyInter2 extends ProxyInter3{ void run(); }public interface ProxyInter3 { void sun(); }下面这个是被代理的类,实现了ProxyInter1,ProxyInter2两个接口public class ProxyImp implements ProxyInter1,ProxyInter2{ @Override public void func() { System.out.println("This is function"); } @Override public void run() { System.out.println("This is run"); } @Override public void sun() { System.out.println("This is sun"); } }下面这个是代理的类的执行:public class MyProxy {     public static void main(String[] args) throws Exception { ProxyInter1 proxyInter1 = new ProxyImp(); ProxyInter2 proxyInter2 = new ProxyImp(); ProxyInter3 proxyInter3 = new ProxyImp(); ProxyInter3 pInter = (ProxyInter3) Proxy.newProxyInstance (proxyInter1.getClass().getClassLoader(), proxyInter1.getClass().getInterfaces(),new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("这是代理之前的事情"); Object object = method.invoke(proxyInter1,args); System.out.println("这是代理之后的事情"); return object;     } }); // pInter.func(); pInter.sun();     } }我的疑问是:1、ProxyInter1,ProxyInter3只是两个接口,没有任何关系,invoke方法里面传的参数为proxyInter1对象,但是上面Proxy.newProxyInstance返回类型为什么是ProxyInter3的类型,却不是ProxyInter1类型的,而且调用的方法只能是ProxyInter3的方法,不能调用ProxyInter1的,2、在Proxy.newProxyInstance方法中,按常理说,调用被代理类的类加载器,被代理类的接口(Interfaces),但是,里面写上proxyInter1,proxyInter2,proxyInter3的三种任意一个都不会报错,问题是ProxyInter1 和ProxyInter2个接口没有任何关系,运行出来一样不会报错,这是什么原因?麻烦各位大佬帮我解答下,让我这个小白涨涨知识。。。。。
查看完整描述

1 回答

已采纳
?
HansonQ

TA贡献223条经验 获得超56个赞

//1、第一个问题你生成的代理对象是给ProxyInter1这个目标对象,但是你却强转为ProxyInter3,这个newProxyInstance方法的返回值是一个Object.既然是另一个对象当然不能调用别的对象方法
//2、第二个我之间诶写的代码
public class MyProxy {
    public static void main(String[] args) {
        final ProxyInter1 proxyInter1 = new ProxyImp();

        ProxyInter2 proxyInter2 = new ProxyImp();
        ProxyInter3 proxyInter3 = new ProxyImp();

        /**
         * Proxy.newProxyInstance
         *          参数1:loader,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存当中
         *              要求:传递的是被代理的类加载器ClassLoader(非必须)
         *              类加载器怎样获取?
         *                  一般情况下:当前类.class.getClassLoader获取加载器
         *                          目标类实例.getClass().getClassLoader获取加载器
         *          参数2:Class[] interfaces:代理类需要实现的所有接口
         *              要求:得到被代理对象所实现的接口的所有Class对象
         *                 方式1:目标类实例.getClass().getInterfaces();注意只能获得自己的接口,不能获得父元素接口
         *                 方式2:new Class[]{UserService.class}
         *                例如:jdbc驱动-->DriverManager 获得接口Connection
         *          参数3:InvocationHandler 处理类,接口,必须进行实现,一般采用匿名内部类
         *                  提供了一个invoke方法,代理类的每一个方法执行时,都将调用一次invoke
         *                      参数 3.1、Object proxy:代理对象
         *                      参数 3.2、Method method:代理对象当前执行的方法的描述对象(反射)
         *                      参数 3.3、Object[] args:方法的实际参数
         */
        ProxyInter1 inter1 = (ProxyInter1) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), proxyInter1.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("call  method before ...");
                Object object = method.invoke(proxyInter1, args);
                System.out.println("call  method after ...");
                return object;
            }
        });
        inter1.func();
    }
}


查看完整回答
反对 回复 2017-09-08
  • 1 回答
  • 0 关注
  • 1182 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信