转-参考https://www.cnblogs.com/gonjan-blog/p/6685611.html
- 摘要:
- 创建动态代理的步骤2步
- 动态代理如何实现代理?(代理对象能做和被代理对象同样的事。)
创建一个动态代理对象步骤:
1.创建一个与被代理对象相关联的InvocationHandler
(InvocationHandler持有一个被代理对象的实例stu)
说明:
Student implements Person;
Student stu;
MyInvocationHandler implements InvocationHandler
InvocationHandler stuHandler = new MyInvocationHandler<Person>(stu);
2.使用Proxy类的getProxyClass静态方法生成一个动态代理类stuProxyClass
Class<?> stuProxyClass = Proxy.getProxyClass(Person.class.getClassLoader(), new Class<?>[] {Person.class});
3.获得stuProxyClass 中一个带InvocationHandler参数的构造器constructor
Constructor<?> constructor = PersonProxy.getConstructor(InvocationHandler.class);
4.通过构造器constructor来创建一个动态实例stuProxy
Person stuProxy = (Person) cons.newInstance(stuHandler);
上面4个步骤可以通过Proxy类的newProxyInstances方法来简化:(2步)
1.创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new MyInvocationHandler<Person>(stu);
2.创建一个代理对象stuProxy,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Proxy.newProxyInstance()
Person stuProxy= (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
Person —> Student—>stu(被代理的实体类的对象/被代理对象)—>stuHandler(中介类)—>stuProxy(代理类)
动态代理如何实现代理?——动态代理原理分析
代理类的对象(代理对象)执行invoke方法,实际上是中介类通过聚合方式持有了被代理对象的引用,然后在invoke()中调用被代理对象的相应方法。
动态代理通过中介类实现了具体的代理功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import proxy.Person;
public final class $Proxy0 extends Proxy implements Person
{
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
}
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("proxy.Person").getMethod("giveMoney", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
public final void giveMoney()
throws
{
try
{
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
}
构造方法,代理类的构造方法,里面的入参是InvocationHandler中介类。
public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
}
静态代码块,让代理类持有了被代理对象的引用。(持有了被代理对象所有方法的引用)
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("proxy.Person").getMethod("giveMoney", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
代理类中和被代理类有着同样的方法,它们都实现了接口Person。(对接口Person中的方法复写)
例如giveMoney(),里面调用了invoke(),invoke的入参有m3,正是被代理对象的giveMoney方法的引用。
代理对象调用方法都是执行InvocationHandler中的invoke方法。
注意:private static Method m3;//Method 类
public final void giveMoney()
throws
{
try
{
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}