A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. package Study.ProxyStudy;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Proxy;

  7. public class ProxyTestThree {

  8.         /**创建代理类的三种方式
  9.          * @param args
  10.          * @throws InvocationTargetException
  11.          * @throws IllegalArgumentException
  12.          * @throws IllegalAccessException
  13.          * @throws InstantiationException
  14.          * @throws SecurityException
  15.          * @throws NoSuchMethodException
  16.          */
  17.         public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  18.                 // TODO Auto-generated method stub
  19.                 fun_A();
  20.                 fun_B();
  21.         }
  22.         public static void fun_A() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  23.                 Class<?> clazz = Proxy.getProxyClass(Test.class.getClassLoader(), A.class, B.class);
  24.                 Constructor<?> con = clazz.getConstructor(InvocationHandler.class);       
  25.                 //创建的代理类对象引用委托类实现接口A
  26.                 A obj = (A) con.newInstance(new InvocationHandler(){
  27.                         Test t = new Test();   //先在匿名内部类的成员位置创建一个目标类(委托类)对象
  28.                         @Override
  29.                         public Object invoke(Object proxy, Method method, Object[] args)
  30.                                         throws Throwable {
  31.                                 // TODO Auto-generated method stub       
  32.                                 Object obj = method.invoke(t, args);
  33.                                 System.out.println("为代理类添加的功能一般是:安全、事务、日志方面的功能");
  34.                                 return obj;
  35.                         }       
  36.                 });
  37.                 obj.println_1();    //只能通过代理类调用接口中覆盖的方法
  38.                 //obj.println_2();    //报错
  39.         }
  40.         public static void fun_B(){
  41.                 B obj = (B) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{A.class, B.class},
  42.                                 new InvocationHandler() {
  43.                                         Test t = new Test();
  44.                                         @Override
  45.                                         public Object invoke(Object proxy, Method method, Object[] args)
  46.                                                         throws Throwable {
  47.                                                 // TODO Auto-generated method stub
  48.                                                 Object obj = method.invoke(t, args);
  49.                                                 System.out.println("为代理类添加的功能一般是:安全、事务、日志方面的功能");
  50.                                                 return obj;
  51.                                         }
  52.                                 });
  53.                 obj.println_2();
  54.         }
  55. }
  56. interface A{
  57.         void println_1();
  58. }
  59. interface B{
  60.         void println_2();
  61. }
  62. //给Test类设计一个代理类
  63. class Test implements A, B{
  64.         @Override
  65.         public void println_1() {
  66.                 // TODO Auto-generated method stub
  67.                 System.out.println("覆盖接口A中的方法");
  68.         }
  69.         @Override
  70.         public void println_2() {
  71.                 // TODO Auto-generated method stub
  72.                 System.out.println("覆盖接口B中的方法");
  73.         }
  74.         public void print3(int i){
  75.                 if(i > 0 ){
  76.                         this.println_1();
  77.                 }
  78.                 else{
  79.                         this.println_2();
  80.                 }
  81.         }
  82. }
复制代码
以上代码中的委托类Test实现了两个接口A、B,本想尝试一下用两种创建代理类的方法(构造器创建、字节码直接创建)来调用委托类中的覆盖方法,可结果是:实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类;并且创建的代理类还不能调用委托类自身的方法?这到底是怎么回事,是不是我的代码和思路出了一点小问题没有发现还是说代理类只能调用一个接口的方法并且不能调用委托类自身的方法,求解释

2 个回复

倒序浏览
实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类?

通过查看创建的代理类中的方法,可以看到代理类中确实有println_1和println_2方法,但是创建的对象只能是A接口或B接口中的一个,创建了A接口的对象就只能用A接口中的方法,你可以这样,创建一个接口C,让A接口和B接口继承自C接口,然后创建C接口的实例对象,就可以调用两个方法了。

并且创建的代理类还不能调用委托类自身的方法?

可以调用委托类自身,在InvocationHandler的invoke方法中只调用委托类方法,不加系统功能不就是委托类原来的方法吗?但是这样做没有什么意义,因为你使用代理类本身就是要区别委托类的方法,如果要使用委托类的方法,可以直接创建委托类的对象啊。
回复 使用道具 举报
WakeUp 发表于 2014-9-30 23:58
实现的代理类只能调用自己一个接口中的覆盖方法,如果想调用另外一个接口中的方法,必须再创建一个委托类? ...

感谢,实现代理类调用两个委托接口中的方法问题解决了
但是调用委托类特有方法的问题还是没有解决?可能是我技术所限,有点没听懂你的解释
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马