jdk动态代理的实现原理(参考其他文章)

第一次看到代理的时候,感觉挺晦涩的,不太清楚是个什么东西,在平时的使用的过程中也用的比较少。然而在spring的AOP编程中,觉得代理这个东西好像还挺神奇,我就特别好奇是怎么实现的,是怎么监听到一个方法的。。所以花了些时间来研究

现在有一个这样的场景,一个接口

public interface StudentInfoService {
void findInfo(String studentName);
}

一个接口的实现类

public class StudentInfoServiceImpl implements StudentInfoService {
public void findInfo(String name) {
System.out.println("你目前输入的名字是:" + name);
}
}

这个时候我某个场景调用findInfo方法的时候,我想在它之前和之后加入我自己的逻辑,就类似如下的

//before
findInfo("zs")
//after

</pre><pre>

 这时候JDK的动态代理就可以帮我们搞定。 

</pre><br /><pre name="code" class="java">public class AOPFactory {
	private static Object getClassInstance(String clzName) {
		Object obj = null;
		try {
			Class cls = Class.forName(clzName);
			obj = (Object) cls.newInstance();
		} catch (ClassNotFoundException cnfe) {
			System.out.println("ClassNotFoundException:" + cnfe.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	public static Object getAOPProxyedObject(String clzName) {
		Object proxy = null;
		MyHandler handler = new MyHandler();
		Object obj = getClassInstance(clzName);
		if (obj != null) {
			proxy = handler.bind(obj);
		} else {
			System.out.println("Can't get the proxyobj");
			//throw
		}
		return proxy;
	}
}

public class MyHandler implements InvocationHandler {
private Object proxyObj;


public Object bind(Object obj) {
this.proxyObj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
System.out.println("before");
System.out.println(method.getName());//findInfo
result = method.invoke(proxyObj, args); //通过反射执行原方法
System.out.println("after");//
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
public class ClientTest {
	public static void main(String[] args) {
		StudentInfoService studentInfo = (StudentInfoService) AOPFactory.getAOPProxyedObject("test.aop.StudentInfoServiceImpl");
		studentInfo.findInfo("阿飞");//其实执行的就是MyHandler 的invoke方法
	}
}
在这里创建的 studentInfo 实例 其实并不是test.aop.StudentInfoServiceImpl的实例,而是一个同样实现了StudentInfoService接口的另外一个类B(先叫做B),在他的findInfo方法里,执行的就是InvocationHandler 的invoke方法,并且会将test.aop.StudentInfoService的findInfo方法对象作为成员变量传递过去。

我们可以在硬盘上找到B的class文件,通过反编译代码如下

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import test.proxy.UserService;

public final class zs extends Proxy
  implements UserService
{
  private static Method m1;
  private static Method m3;//就是findInfo方法
  private static Method m0;
  private static Method m2;

  public zs(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 findInfo()
    throws 
  {
    try
    {
      super.h.invoke(this, m3, null);//h就是InvocationHandler对象
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      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 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("test.proxy.StudentInfoService").getMethod("findInfo", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      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());
    }
  }
}
这样就是整个jdk动态代理的过程






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值