JDK 動態代理對異常的處理及InvocationTargetException異常解析

// 接口IA
public interface IA{
   public void run()throws IOException;
}
// 實現類
public class IAImpl implements IA{
@Override
  public void run() throws IOException{
     System.out.println("IAImpl的run方法");
     throw new IOException();·
  }
}
// InvocationHandle的實現
class InvocationHandlerImpl implements InvocationHandler {
        
//目標對象
private Object target; 
public InvocationHandlerImpl(Object target){
      this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {·
      Object result = null;
        
      System.out.println("before...");
      // 調用目標方法,目標方法所有的異常會被包裝成InvocationTargetException異常往上拋
      try {
          result = method.invoke(this.target, args);
      } catch (InvocationTargetException e) {       // 如果這裏返貨捕獲InvocationTargetException 異常並且返回原始異常,則動態代理接收到的就是InvocationTargetException異常
        throw e.getTargetException();              
      // 如果是InvocationTargetException 異常,則返回被包裝的目標方法原始異常(Spring AOP調用目標方法後拋出異常也是這樣實現)
      // 因爲此異常沒被聲明,最終會被動態代理包成爲UndeclaredThrowableException異常
      }      
      System.out.println("after...");      
      return result;
}

}


public class JdkProxyTest {
  public static void main(String[] args) {  

// 創建目標類對象
IA target = new IAImpl();
 
// 創建代理了目標類IAImpl的動態代理,根據不同的目標對象,生成不同的動態代理字節碼
IA dynamicProxy = (IA)Proxy.newProxyInstance(
               target.getClass().getClassLoader(),
               target.getClass().getInterfaces(),
               new InvocationHandlerImpl(target));

// 調用動態代理的方法
try {
dynamicProxy.run();
} catch (IOException e) { // 能捕獲到動態代理拋出的IOException異常
e.printStackTrace();
}

  }

}

具體Proxy在運行期生成的動態代理類的字節碼反編譯後如下:

package aop;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy
  implements IA
{
  private static Method m1;
  private static Method m3;
  private static Method m0;
  private static Method m4;
  private static Method m2;

  public $Proxy0(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }


  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (RuntimeException localRuntimeException)
    {
       throw localRuntimeException;
    }

    catch (Throwable localThrowable)
    { 

      throw new UndeclaredThrowableException(localThrowable);
    }
   
  }

  public final void run()
    throws IOException
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException) // 如果是運行是異常,則直接拋出
    {
      throw localRuntimeException;
    }

   catch (IOException iOexception) // 如果是方法聲明的異常,則直接拋出  
    {
      throw iOexception;
    }
    catch (Throwable localThrowable) // 如果異常沒被聲明,則最終被代理對象包裝成運行期異常UndeclaredThrowableException拋出
    {

     throw new UndeclaredThrowableException(localThrowable);
    }

  }

  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
    }
    throw new UndeclaredThrowableException(localThrowable);
  }


  public final String show(String paramString)
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m4, new Object[] { paramString });
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
    }
    throw new UndeclaredThrowableException(localThrowable);
  }

  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
    }
    throw new UndeclaredThrowableException(localThrowable);
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("aop.IA").getMethod("run", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m4 = Class.forName("aop.IA").getMethod("show", new Class[] { Class.forName("java.lang.String") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
    }
    throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
  }
}


  


發佈了49 篇原創文章 · 獲贊 30 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章