一, 动态代理是利用 Java 反射机制实现的
JAVA 反射机制: 在运行状态中, 对于任意一个实体类, 都能够知道这个类的所有属性和方法; 对于任意一个对象, 都能够调用它的任意方法和属性; 这种动态获取信息以及动态调用对象方法的功能称为 java 语言的反射机制.
类加载过程中的加载过程会在内存中生成一个代表此 Class 文件的 java.lang.Class 对象, 作为方法区这个类的各种数据的访问入口. 通过这个 Class 的实例对象, 可以知道这个类的所有属性和方法.
JDK 中反射包 java.lang.reflect 则提供了操作这个类的任意方法和属性的设计. java.lang.reflect 包中主要实体类 Method,Field,Constructor 分别对应着类的方法, 属性及构造方法,
另外反射包中的 Proxy 类与 InvocationHandler 接口是实现了动态代理的超类与接口
java.lang.reflect.Proxy 提供用于创建动态代理类和实例的静态方法, 它还是由这些方法创建的所有动态代理类的超类.
java.lang.reflect.InvocationHandler 是代理实例的调用处理程序 实现的接口.
二, 动态代理的实现例子
- public class DynamicProxyTest {
- interface IHello{
- void sayHello();
- }
- static class Hello implements IHello{
- @Override
- public void sayHello() {
- System.out.println("hello world");
- }
- }
- static class DynamicProxy implements InvocationHandler{
- Object target;
- Object bind(Object target){
- this.target = target;
- return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("welcome");
- return method.invoke(target,args);
- }
- }
- public static void main(String[] args){
- IHello target = new Hello();
- System.out.println(target.getClass().getClassLoader());
- System.out.println(Arrays.toString(target.getClass().getInterfaces()));
- System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");// 在对应 package 下生成代理类 $Proxy0.class
- IHello hello = (IHello) new DynamicProxy().bind(target);
- hello.sayHello();
- }
- }
其中 Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this) 这行代码生成的代理类 $Proxy0.class, 如下
- package com.sun.proxy;
- import com.App.proxy.IHello;
- 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 IHello {
- private static Method m1;
- private static Method m3;
- private static Method m2;
- private static Method m0;
- public $Proxy0(InvocationHandler var1) throws {
- super(var1);
- }
- public final boolean equals(Object var1) throws {
- try {
- return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
- } catch (RuntimeException | Error var3) {
- throw var3;
- } catch (Throwable var4) {
- throw new UndeclaredThrowableException(var4);
- }
- }
- public final void sayHello() throws {
- try {
- super.h.invoke(this, m3, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- public final String toString() throws {
- try {
- return (String)super.h.invoke(this, m2, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- public final int hashCode() throws {
- try {
- return (Integer)super.h.invoke(this, m0, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- static {
- try {
- m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
- m3 = Class.forName("com.app.proxy.IHello").getMethod("sayHello");
- m2 = Class.forName("java.lang.Object").getMethod("toString");
- m0 = Class.forName("java.lang.Object").getMethod("hashCode");
- } catch (NoSuchMethodException var2) {
- throw new NoSuchMethodError(var2.getMessage());
- } catch (ClassNotFoundException var3) {
- throw new NoClassDefFoundError(var3.getMessage());
- }
- }
- }
来源: http://www.bubuko.com/infodetail-3358551.html