代理模式(五)JDK动态代理深入分析
2016-03-12 12:43
417 查看
JDK动态代理实现的核心技术是java反射机制,其主要的两个类是:Proxy、InvocationHandler。使用
使用
[java] view
plain copy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
interfaces:该动态代理类所要实现的接口
函数返回创建的代理类,实现了interfaces接口
例如:
[java] view
plain copy
InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface) Proxy.ne
4000
wProxyInstance(
MyInterface.class.getClassLoader(),
new Class[] { MyInterface.class },
handler);
函数返回值强转成MyInterface类型,所有对代理类的调用都将转发到实现了InvocationHandler的handler对象中。
[java] view
plain copy
public interface InvocationHandler{
Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
例如:
[java] view
plain copy
public class MyInvocationHandler implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//do something "dynamic"
}
}
Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,客户端通常需要针对抽象主题角色进行编程(面向接口编程)。
[java] view
plain copy
package com.markliu.proxy;
/**
* 抽象角色;动态代理只能代理接口
* @author markliu
*
*/
public interface Subject {
public void request();
}
DynamicInvocationHandler(代理主题中的业务处理角色):它包含了对真实主题的引用(对象组合),从而可以在invoke方法中操作真实主题对象;在代理主题角色中提供一个实现与真实主题角色相同接口的对象realSubject,以便在任何时候都可以替代真实主题;在代理主题角色中,invoke函数在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。
[java] view
plain copy
package com.markliu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理类
* 实现了InvocationHandler
* @author markliu
*
*/
public class DynamicInvocationHandler implements InvocationHandler {
// 这是动态代理的好处,被封装的对象是Object类型,接受任意类型的对象
private Object realSubject; // 保存的是真实对象
public DynamicInvocationHandler() {
}
public DynamicInvocationHandler(Object realSubject) {
this.realSubject = realSubject;
}
/*
* 这个方法不是我们显示的去调用
* 实际内部调用的形式是invoke(this, m3, null);
* this指$Proxy0动态代理对象,
* m3代表$Proxy0所实现的接口Subject中的request的方法对象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling " + method);
method.invoke(realSubject, args);
System.out.println("after calling " + method);
return null;
}
}
RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。
[java] view
plain copy
package com.markliu.proxy;
/**
* 真实角色->被代理类:实现了Subject的request()方法
* @author markliu
*
*/
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("From real subject.");
}
}
客户端测试代码:
[java] view
plain copy
package com.markliu.proxy;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 客户端:生成代理实例,并调用了request()方法
* @author markliu
*/
public class Client {
public static void main(String[] args) throws Throwable {
// 真实角色->被代理类
Subject realSubject = new RealSubject();
// 调用处理的业务具体实现
InvocationHandler h = new DynamicInvocationHandler(realSubject);
// Returns the runtime class of this Object
Class<?> cls = realSubject.getClass();
/*
* 动态代理类
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation handler.
* 返回一个指定接口的proxy类对象,用于将方法调用分派到指定的InvocationHandler中
*
* cls.getInterfaces(): 获取cls所对应的类RealSubject锁实现的接口,即Subject
* 因此创建的Proxy的一个实例实现了动态指定的接口!
*/
Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
// 这里可以通过运行结果证明subject是Proxy的一个实例,这个实例实现了Subject接口
System.out.println(subject instanceof Proxy);
// 这里可以看出subject的Class类是$Proxy0,这个$Proxy0类继承了Proxy,实现了Subject接口
System.out.println("subject的Class类是:" + subject.getClass().toString());
System.out.print("subject中的属性有:");
Field[] field = subject.getClass().getDeclaredFields();
for (Field f : field) {
System.out.print(f.getName() + ", ");
}
System.out.print("\n" + "subject中的方法有:");
Method[] method = subject.getClass().getDeclaredMethods();
for (Method m : method) {
System.out.print(m.getName() + ", ");
}
System.out.println("\n" + "subject的父类是:" + subject.getClass().getSuperclass());
System.out.print("subject实现的接口是:");
Class<?>[] interfaces = subject.getClass().getInterfaces();
for (Class<?> i : interfaces) {
System.out.print(i.getName() + ", ");
}
System.out.println("\n\n" + "运行结果为:");
subject.request();
}
}
程序运行结果:
[java] view
plain copy
true
subject的Class类是:class com.sun.proxy.$Proxy0
subject中的属性有:m1, m2, m3, m0,
subject中的方法有:request, equals, toString, hashCode,
subject的父类是:class java.lang.reflect.Proxy
subject实现的接口是:com.markliu.proxy.Subject,
运行结果为:
before calling public abstract void com.markliu.proxy.Subject.request()
From real subject.
after calling public abstract void com.markliu.proxy.Subject.request()
这个结果的信息非常重要。要理解subject和Proxy之间的联系,request()和invoke()的调用关系。
由运行结果可以看出:
subject instanceof Proxy为true,subject是Proxy的一个实例,这个实例实现了Subject接口
subject的Class类是com.sun.proxy.$Proxy0,是一个通过反射机制动态生成的,下面分析其源代码
subject中只有四个方法,其中一个就是抽象主题角色中的方法request
从Client中的代码看,从newProxyInstance这个方法入手,看一下Proxy类中newProxyInstance方法的源代码,是如何将interfaces和invacationhandler建立联系,创建了动态代理类。
[java] view
plain copy
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
...
final Class<?>[] intfs = interfaces.clone();
/*
* 根据类加载器loader获取实现intfs接口的类类型,其实就是com.sun.proxy.$Proxy0
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* 通过指定的handler调用com.sun.proxy.$Proxy0的构造方法.
*/
try {
...
/*
* 获取public类型的构造函数
* 其中有定义private static final Class<?>[] constructorParams = { InvocationHandler.class };
* 打开getConstructor(constructorParams)方法:
* 会看到底层调用的是:
* private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
*int which) throws NoSuchMethodException
* {
* // 获取所有的public类型的构造函数
* Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
* for (Constructor<T> constructor : constructors) {
* // 如果传入的构造函数的参数parameterTypes(也就是客户端传入的实现InvocationHandler接口的对象h)
* // 与其中的public类型的构造函数的参数匹配,就返回该构造函数,即此Demo中的public DynamicProxySubject(Object realSubject);
* // 从而实现了在动态代理类中持有InvocationHandler的引用,则可以调用invoke方法
*if (arrayContentsEq(parameterTypes, constructor.getParameterTypes())) {
* return getReflectionFactory().copyConstructor(constructor);
*}
* }
* throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
* }
*/
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 此处创建了该实例,传入InvocationHandler对象
return cons.newInstance(new Object[]{h});
} catch (Exception e) {
...
}
}
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler
h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy0。$Proxy0类 实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把InvocationHandler对象传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
[java] view
plain copy
public class Proxy implements java.io.Serializable {
protected InvocationHandler h;
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
...
}
这样该动态代理类就持有InvocationHandler的引用,则可以调用invoke方法。下面具体看下该动态代理类,继承了Proxy的$Proxy0的源代码:
[java] view
plain copy
package com.markliu.proxy;
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 Subject {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("***.RealSubject").getMethod("request",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void request() {
try {
// 此处调用了InvocationHandler接口中的invoke方法!
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}
所以可以看出动态代理类$Proxy0实现了Subject接口,在Demo中调用subject.request()时,由里氏代换原则知,将调用$Proxy0中的request的方法,最终调用实现InvocationHandler接口的invoke方法。
总结:JDK动态代理的类结构如下:
因为java已经为我们创建了Proxy类,所以需要有办法告诉Proxy类你需要做什么。你不能像以前一样直接把代码放在Proxy类中,因为Proxy类不是你直接实现的。需要将实际添加的业务逻辑放在实现InvocationHandler中。InvocationHandler的工作是响应代理的任何调用,即调用生成的代理类的方法时最终会交给InvocationHandler的invoke方法,其中就会调用RealSubject的方法。你可以把InvocationHandler想成是代理收到方法调用后,请求做实际业务处理的对象。
转载出处:http://blog.csdn.net/mark_lq/article/details/48178497
博主:SunnyMarkLiu
java.lang.reflect.Proxy类可以动态实现接口作为代理类。
一. Creating Proxies
使用Proxy.newProxyInstance()方法创建动态代理类,方法定义:
[java] view
plain copy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
ClassLoader:加载动态代理类的类加载器
interfaces:该动态代理类所要实现的接口
InvocationHandler:事件处理,转发所有的方法调用代理。
函数返回创建的代理类,实现了interfaces接口
例如:
[java] view
plain copy
InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface) Proxy.ne
4000
wProxyInstance(
MyInterface.class.getClassLoader(),
new Class[] { MyInterface.class },
handler);
函数返回值强转成MyInterface类型,所有对代理类的调用都将转发到实现了InvocationHandler的handler对象中。
二. InvocationHandler's
Proxy.newProxyInstance()方法中需要传入实现InvocationHandler的对象,proxy方法的调用才能转发到InvocationHandler的实现对象中。
[java] view
plain copy
public interface InvocationHandler{
Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
例如:
[java] view
plain copy
public class MyInvocationHandler implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//do something "dynamic"
}
}
1. proxy就是通过
Proxy.newProxyInstance()方法创建的动态代理类,它实现了指定的interfaces接口。 通常这个对象在invoke函数中不使用。
2. Method表示动态代理类所实现的接口中的方法。通过
Method对象可以获取方法名、参数类型、返回类型等信息。
3. Object[] args包含了传入动态代理类所实现的方法的参数值。
三. JDK动态代理类Demo及原理分析
Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,客户端通常需要针对抽象主题角色进行编程(面向接口编程)。[java] view
plain copy
package com.markliu.proxy;
/**
* 抽象角色;动态代理只能代理接口
* @author markliu
*
*/
public interface Subject {
public void request();
}
DynamicInvocationHandler(代理主题中的业务处理角色):它包含了对真实主题的引用(对象组合),从而可以在invoke方法中操作真实主题对象;在代理主题角色中提供一个实现与真实主题角色相同接口的对象realSubject,以便在任何时候都可以替代真实主题;在代理主题角色中,invoke函数在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。
[java] view
plain copy
package com.markliu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理类
* 实现了InvocationHandler
* @author markliu
*
*/
public class DynamicInvocationHandler implements InvocationHandler {
// 这是动态代理的好处,被封装的对象是Object类型,接受任意类型的对象
private Object realSubject; // 保存的是真实对象
public DynamicInvocationHandler() {
}
public DynamicInvocationHandler(Object realSubject) {
this.realSubject = realSubject;
}
/*
* 这个方法不是我们显示的去调用
* 实际内部调用的形式是invoke(this, m3, null);
* this指$Proxy0动态代理对象,
* m3代表$Proxy0所实现的接口Subject中的request的方法对象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling " + method);
method.invoke(realSubject, args);
System.out.println("after calling " + method);
return null;
}
}
RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。
[java] view
plain copy
package com.markliu.proxy;
/**
* 真实角色->被代理类:实现了Subject的request()方法
* @author markliu
*
*/
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("From real subject.");
}
}
客户端测试代码:
[java] view
plain copy
package com.markliu.proxy;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 客户端:生成代理实例,并调用了request()方法
* @author markliu
*/
public class Client {
public static void main(String[] args) throws Throwable {
// 真实角色->被代理类
Subject realSubject = new RealSubject();
// 调用处理的业务具体实现
InvocationHandler h = new DynamicInvocationHandler(realSubject);
// Returns the runtime class of this Object
Class<?> cls = realSubject.getClass();
/*
* 动态代理类
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation handler.
* 返回一个指定接口的proxy类对象,用于将方法调用分派到指定的InvocationHandler中
*
* cls.getInterfaces(): 获取cls所对应的类RealSubject锁实现的接口,即Subject
* 因此创建的Proxy的一个实例实现了动态指定的接口!
*/
Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
// 这里可以通过运行结果证明subject是Proxy的一个实例,这个实例实现了Subject接口
System.out.println(subject instanceof Proxy);
// 这里可以看出subject的Class类是$Proxy0,这个$Proxy0类继承了Proxy,实现了Subject接口
System.out.println("subject的Class类是:" + subject.getClass().toString());
System.out.print("subject中的属性有:");
Field[] field = subject.getClass().getDeclaredFields();
for (Field f : field) {
System.out.print(f.getName() + ", ");
}
System.out.print("\n" + "subject中的方法有:");
Method[] method = subject.getClass().getDeclaredMethods();
for (Method m : method) {
System.out.print(m.getName() + ", ");
}
System.out.println("\n" + "subject的父类是:" + subject.getClass().getSuperclass());
System.out.print("subject实现的接口是:");
Class<?>[] interfaces = subject.getClass().getInterfaces();
for (Class<?> i : interfaces) {
System.out.print(i.getName() + ", ");
}
System.out.println("\n\n" + "运行结果为:");
subject.request();
}
}
程序运行结果:
[java] view
plain copy
true
subject的Class类是:class com.sun.proxy.$Proxy0
subject中的属性有:m1, m2, m3, m0,
subject中的方法有:request, equals, toString, hashCode,
subject的父类是:class java.lang.reflect.Proxy
subject实现的接口是:com.markliu.proxy.Subject,
运行结果为:
before calling public abstract void com.markliu.proxy.Subject.request()
From real subject.
after calling public abstract void com.markliu.proxy.Subject.request()
这个结果的信息非常重要。要理解subject和Proxy之间的联系,request()和invoke()的调用关系。
由运行结果可以看出:
subject instanceof Proxy为true,subject是Proxy的一个实例,这个实例实现了Subject接口
subject的Class类是com.sun.proxy.$Proxy0,是一个通过反射机制动态生成的,下面分析其源代码
subject中只有四个方法,其中一个就是抽象主题角色中的方法request
从Client中的代码看,从newProxyInstance这个方法入手,看一下Proxy类中newProxyInstance方法的源代码,是如何将interfaces和invacationhandler建立联系,创建了动态代理类。
[java] view
plain copy
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
...
final Class<?>[] intfs = interfaces.clone();
/*
* 根据类加载器loader获取实现intfs接口的类类型,其实就是com.sun.proxy.$Proxy0
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* 通过指定的handler调用com.sun.proxy.$Proxy0的构造方法.
*/
try {
...
/*
* 获取public类型的构造函数
* 其中有定义private static final Class<?>[] constructorParams = { InvocationHandler.class };
* 打开getConstructor(constructorParams)方法:
* 会看到底层调用的是:
* private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
*int which) throws NoSuchMethodException
* {
* // 获取所有的public类型的构造函数
* Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
* for (Constructor<T> constructor : constructors) {
* // 如果传入的构造函数的参数parameterTypes(也就是客户端传入的实现InvocationHandler接口的对象h)
* // 与其中的public类型的构造函数的参数匹配,就返回该构造函数,即此Demo中的public DynamicProxySubject(Object realSubject);
* // 从而实现了在动态代理类中持有InvocationHandler的引用,则可以调用invoke方法
*if (arrayContentsEq(parameterTypes, constructor.getParameterTypes())) {
* return getReflectionFactory().copyConstructor(constructor);
*}
* }
* throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
* }
*/
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 此处创建了该实例,传入InvocationHandler对象
return cons.newInstance(new Object[]{h});
} catch (Exception e) {
...
}
}
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler
h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy0。$Proxy0类 实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把InvocationHandler对象传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
[java] view
plain copy
public class Proxy implements java.io.Serializable {
protected InvocationHandler h;
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
...
}
这样该动态代理类就持有InvocationHandler的引用,则可以调用invoke方法。下面具体看下该动态代理类,继承了Proxy的$Proxy0的源代码:
[java] view
plain copy
package com.markliu.proxy;
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 Subject {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("***.RealSubject").getMethod("request",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void request() {
try {
// 此处调用了InvocationHandler接口中的invoke方法!
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}
所以可以看出动态代理类$Proxy0实现了Subject接口,在Demo中调用subject.request()时,由里氏代换原则知,将调用$Proxy0中的request的方法,最终调用实现InvocationHandler接口的invoke方法。
总结:JDK动态代理的类结构如下:
因为java已经为我们创建了Proxy类,所以需要有办法告诉Proxy类你需要做什么。你不能像以前一样直接把代码放在Proxy类中,因为Proxy类不是你直接实现的。需要将实际添加的业务逻辑放在实现InvocationHandler中。InvocationHandler的工作是响应代理的任何调用,即调用生成的代理类的方法时最终会交给InvocationHandler的invoke方法,其中就会调用RealSubject的方法。你可以把InvocationHandler想成是代理收到方法调用后,请求做实际业务处理的对象。
转载出处:http://blog.csdn.net/mark_lq/article/details/48178497
博主:SunnyMarkLiu
相关文章推荐
- Eclipse安装SVN
- IT十八掌作业_java基础第八天_多线程
- Java的枚举值能不能用==比较?
- Java代理 Notes
- java解析xml
- java list中的对象去重原理
- 20145314郑凯杰 《Java程序设计》第2周学习总结 代码开始!
- eclipse web module版本问题:Cannot change version of project facet Dynamic Web Module to 2.5.
- 九、Null在Java中的精确表示
- Spring4 mvc 基础教程~非常适合新手
- 八、Java的可变参数例子
- 七、如何在Java中高效检查一个数组是否含有一个值
- java多线程总结
- Lock与synchronized 的区别
- Android使用eclipse开发导入源码包相关问题
- java SE基础(文件和流)
- Windows下Eclipse导入android系统源码
- JAVA线程生命周期
- springmvc学习笔记(16)-异常处理器
- springmvc学习笔记(15)-数据回显