JDK中的动态代理之二

JDK中的动态代理之二
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)throws IllegalArgumentException{
                   if (h == null) {    throw new NullPointerException();                  }        //InvocationHandler为null抛出异常
                   Class cl = getProxyClass(loader, interfaces);                               //使用上面的方法得到一个ProxyClass
                   try {
                       Constructor cons = cl.getConstructor(constructorParams);         //得到此类的构造器
                       return (Object) cons.newInstance(new Object[] { h });                  //使用Handler构造对象
                   } catch (NoSuchMethodException e) {
                       throw new InternalError(e.toString());
                   } catch (IllegalAccessException e) {
                       throw new InternalError(e.toString());
                   } catch (InstantiationException e) {
                       throw new InternalError(e.toString());
                   } catch (InvocationTargetException e) {
                       throw new InternalError(e.toString());
                   }
    } 
    public static boolean isProxyClass(Class<?> cl) {                                          //判断某个Class是否为ProxyClass
                   if (cl == null) {    throw new NullPointerException();      }                 //输入为null抛出异常
                   return proxyClasses.containsKey(cl);                                          //返回该Proxy的Chche中是否存在该Class
    } 
         //得到某个ProxyClass对象对应的InvocationHandler
    public static InvocationHandler getInvocationHandler(Object proxy)throws IllegalArgumentException{
                   if (!isProxyClass(proxy.getClass())) {               //该对象不是ProxyClass则抛出异常
                       throw new IllegalArgumentException("not a proxy instance");
                   }       
                   Proxy p = (Proxy) proxy;                                 //是ProxyClass则downcast
                   return p.h;                                                          //返回此ProxyClass的成员变量
}        
// 到目前为止,我们可以猜测在创建 ProxyClass 时,
// 肯定使用该 Proxy 类的子类或者其 protected 的构造器中的一种 
private static native Class defineClass0(ClassLoader loader, String name, byte[] b, int off, int len);
//使用JNI创建一个Class
         上面使用多个Cache,以下是这些Cache的层次图:
 
四、使用动态代理的例子
         下面给出一个具体的例子: 
//ServiceIF.java
public interface ServiceIF {
         public void doService();
       以上是具体提供服务的对象的接口。下面给出其实现。 
//Service.java
public class Service implements ServiceIF{
         public void doService(){
                   System.out.println("正在执行您申请的服务!");                
         }
       使用JDK中的动态代理时必须实现InvocationHandler接口,实现该接口的对象一般会封装代理模式中的目标对象,同时实现其中的invoke方法。以下是实现该接口的代码: 
//DynamicProxyInvocationHandler.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; 
public class DynamicProxyInvocationHandler implements InvocationHandler {
   private Object realService = null;   
   public DynamicProxyInvocationHandler(Object service) {
      this.realService = service;
   }   
   public Object invoke(Object proxy, Method m, Object[] args){
      Object result = null;
      System.out.println("您正在申请服务" + m.getName());
      try {
         result = m.invoke(realService , args);  
      }catch(Exception ex) {
         System.exit(1);
      }
      System.out.println("您申请的服务 " + m.getName() + " 已经完成 ");
      return result;
   } 
}
 
       接口中的invoke方法包含三个参数:Object、Method、Object[],同时包含一个Object类型的返回值。该方法的含义为:使用Object[]类型的参数列表args调用proxy对象的m方法,返回Object类型的对象。 在上面的实现中,在调用具体对象的方法前首先打印正在申请某个对象的某个方法,接着调用某个对象的某个方法,在调用具体对象的方法后打印申请的服务已经完成。这就是我们上面所说的为真实对象增加功能。下面是一段最后的测试代码: 
//DynamicProxyTest.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; 
public class DynamicProxyTest {
   public static void main(String args[]) {
      Service realService = new Service();
      ServiceIF proxy = (ServiceIF)Proxy.newProxyInstance(
                        realService.getClass().getClassLoader(),
                        realService.getClass().getInterfaces(),
                        new DynamicProxyInvocationHandler(realService));
      proxy.doService();
   } 
       在测试中首先创建一个真实的服务对象,即代理模式中的目标对象,然后使用Proxy类的newProxyInstance静态方法,创建一个具体的代理对象,由于代理对象和被代理对象具有相同的接口ServiceIF,因此我们在该代理对象被创建后downcast为ServiceIF接口,接着调用该代理对象的服务方法。下图是执行结果图:
        
         有兴趣可以继续研究编译器的实现、字节码的细节、以及虚拟机的实现。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值