黑马程序员技术交流社区
标题:
一个关于动态代理的问题,即如果委托类实现了两个接口...
[打印本页]
作者:
贾浩田
时间:
2014-9-30 21:46
标题:
一个关于动态代理的问题,即如果委托类实现了两个接口...
package Study.ProxyStudy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTestThree {
/**创建代理类的三种方式
* @param args
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SecurityException
* @throws NoSuchMethodException
*/
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
fun_A();
fun_B();
}
public static void fun_A() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<?> clazz = Proxy.getProxyClass(Test.class.getClassLoader(), A.class, B.class);
Constructor<?> con = clazz.getConstructor(InvocationHandler.class);
//创建的代理类对象引用委托类实现接口A
A obj = (A) con.newInstance(new InvocationHandler(){
Test t = new Test(); //先在匿名内部类的成员位置创建一个目标类(委托类)对象
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object obj = method.invoke(t, args);
System.out.println("为代理类添加的功能一般是:安全、事务、日志方面的功能");
return obj;
}
});
obj.println_1(); //只能通过代理类调用接口中覆盖的方法
//obj.println_2(); //报错
}
public static void fun_B(){
B obj = (B) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{A.class, B.class},
new InvocationHandler() {
Test t = new Test();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object obj = method.invoke(t, args);
System.out.println("为代理类添加的功能一般是:安全、事务、日志方面的功能");
return obj;
}
});
obj.println_2();
}
}
interface A{
void println_1();
}
interface B{
void println_2();
}
//给Test类设计一个代理类
class Test implements A, B{
@Override
public void println_1() {
// TODO Auto-generated method stub
System.out.println("覆盖接口A中的方法");
}
@Override
public void println_2() {
// TODO Auto-generated method stub
System.out.println("覆盖接口B中的方法");
}
public void print3(int i){
if(i > 0 ){
this.println_1();
}
else{
this.println_2();
}
}
}
复制代码
以上代码中的委托类Test实现了两个接口A、B,本想尝试一下用两种创建代理类的方法(构造器创建、字节码直接创建)来调用委托类中的覆盖方法,可结果是:实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类;并且创建的代理类还不能调用委托类自身的方法?这到底是怎么回事,是不是我的代码和思路出了一点小问题没有发现还是说代理类只能调用一个接口的方法并且不能调用委托类自身的方法,求解释
作者:
WakeUp
时间:
2014-9-30 23:58
实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类?
通过查看创建的代理类中的方法,可以看到代理类中确实有println_1和println_2方法,但是创建的对象只能是A接口或B接口中的一个,创建了A接口的对象就只能用A接口中的方法,你可以这样,创建一个接口C,让A接口和B接口继承自C接口,然后创建C接口的实例对象,就可以调用两个方法了。
并且创建的代理类还不能调用委托类自身的方法?
可以调用委托类自身,在InvocationHandler的invoke方法中只调用委托类方法,不加系统功能不就是委托类原来的方法吗?但是这样做没有什么意义,因为你使用代理类本身就是要区别委托类的方法,如果要使用委托类的方法,可以直接创建委托类的对象啊。
作者:
贾浩田
时间:
2014-10-2 22:48
WakeUp 发表于 2014-9-30 23:58
实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类? ...
感谢,实现代理类调用两个委托接口中的方法问题解决了
但是调用委托类特有方法的问题还是没有解决?可能是我技术所限,有点没听懂你的解释
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2