猿问

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

关于动态代理的那些事 (JDK的动态代理)

有3个接口,分别为ProxyInter1,ProxyInter2,ProxyInter3,但是接口2继承接口3


public 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个接口没有任何关系,运行出来一样不会报错,这是什么原因?


麻烦各位大佬帮我解答下,让我这个小白涨涨知识。。。。。

有一种放弃叫三分热情
浏览 1223回答 1
1回答

HansonQ

//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();     } }
随时随地看视频慕课网APP

相关分类

Java
我要回答