- 浏览: 1591327 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (289)
- java 语法基础 (51)
- spring (8)
- mvc struct /Ant --build.xml (8)
- SOA (0)
- oracle 9i/10g (23)
- sql server 2000-2005 (3)
- 数据库基础知识 (6)
- 设计模式与软件架构 (10)
- Hibernate 持久化 (9)
- J2SE/J2EE/J2ME/AJAX 技术 (8)
- JSF 技术 (3)
- JAVA 图形化 (0)
- JMS (40)
- Eclipse 3.2 IDE 开发技巧 (13)
- 项目处理方法集合 (2)
- html/jsp/javascript (2)
- Unix/Linux (9)
- j2me/ARM/windriver/嵌入式 (4)
- 电信科学 (8)
- jsp (1)
- c/c++ (1)
- LZW压缩算法(java) (2)
- Android (77)
- 版本管理git/svn (2)
最新评论
-
huihai:
有demo吗?
NamingStrategy实现动态表名映射 -
cangbaotu:
推荐给大家一些有用的爬虫源码:https://github.c ...
网络爬虫(源代码参考) -
tuspark:
除了.classpath文件以外,.project文件也应该了 ...
Eclipse .classpath文件浅谈 -
tuspark:
造成eclipse自动关闭的原因有很多,这里有很多介绍:ecl ...
eclipse 自动关闭 解决方案 -
DEMONU:
网上都是这些,这种文章。。。
ActiveMQ中的消息持久性
Java 1.3引入了名为“动态代理类”(Dynamic Proxy Class)的新特性,利用它可为“已知接口的实现”动态地创建包装器(wrapper)类。1.3版本问世以前,当我首次听说当时正在提议的动态代理类时,还以为它只是一种用来吸引人的眼球的特性。虽然把它包括到语言中是一件好事,但我却想不出它有任何实际用处。带着这一成见,我试着用动态代理写了一个示例程序,却惊讶于它的巨大威力,并当即决定把它放到我的工具箱中,以便在将来的项目中使用。此后,我不断体验到它的好处,它总是能用正确的方法来做你想要做的事情!
假如没有动态代理
深入探索动态代理类之前,先来看看在某些情况下,假如没有动态代理类会是什么样子:
public interface Robot {
void moveTo(int x, int y);
void workOn(Project p, Tool t);
}
public class MyRobot implements Robot {
public void moveTo(int x, int y) {
// stuff happens here
}
public void workOn(Project p, Tool t) {
// optionally destructive stuff happens here
}
}
上述代码展示了一个名为Robot的接口,以及该接口的一个名为MyRobot的大致的实现。假定你现在想拦截对MyRobot类发出的方法调用(可能是为了限制一个参数的值)。
public class BuilderRobot implements Robot {
private Robot wrapped;
public BuilderRobot(Robot r) {
wrapped = r;
}
public void moveTo(int x, int y) {
wrapped.moveTo(x, y);
}
public void workOn(Project p, Tool t) {
if (t.isDestructive()) {
t = Tool.RATCHET;
}
wrapped.workOn(p, t);
}
}
一个办法就是使用显式的包装器类,就像上面显示的那样。BuilderRobot类在其构造函数中获取一个Robot,并拦截workOn方法,确保在任何项目中使用的工具都没有破坏性。另外,由于BuilderRobot这一包装器实现了Robot接口,所以凡是能够使用一个Robot的任何地方,都能使用一个BuilderRobot实例。
对于这种包装器风格的BuilderRobot来说,一旦你想修改或扩展Robot接口,它的缺点就会暴露无遗。为Robot接口添加一个方法,就得为BuilderRobot类添加一个包装器方法。为Robot添加10个方法,就得为BuilderRobot添加10个方法。如果BuilderRobot、CrusherRobot、SpeedyRobot和SlowRobot都是Robot包装器类,就必须分别为它们添加10个方法。这显然是效率极差的一种方案。
public class BuilderRobot extends MyRobot {
public void workOn(Project p, Tool t) {
if (t.isDestructive()) {
t = Tool.RATCHET;
}
super.workOn(p, t);
}
}
上述代码是对 BuilderRobot进行编程的另一种方式。注意BuilderRobot变成了MyRobot的一个子类。这样可解决在第2段代码的包装器方案中出现的问题。也就是说,修改Robot接口不必修改BuilderRobot。但这又产生了一个新问题:只有MyRobot对象才能是BuilderRobot。而在此之前,实现了Robot接口的任何对象都可以成为一个BuilderRobot。现在,由Java施加的“线性类出身限制”(linear class parentage restrictions)禁止我们将任意Robot(ArbitraryRobot)变成一个BuilderRobot。
动态代理也有限制
动态代理则综合了以上两种方案的优点。使用动态代理,你创建的包装器类不要求为所有方法都使用显式的包装器,创建的子类也不要求具有严格的出身,两者方法可任选一种你认为最好的。但是,动态代理仍然有一个限制。当你使用动态代理时,要包装/扩展的对象必须实现一个接口,该接口定义了准备在包装器中使用的所有方法。这一限制的宗旨是鼓励良好的设计,而不是为你带来更多的麻烦。根据经验,每个类都至少应该实现一个接口(nonconstant接口)。良好的接口用法不仅使动态代理成为可能,还有利于程序的模块化。
使用动态代理
下面的代码演示了用动态代理来创建一个BuilderRobot时所必需的类。注意我们创建的这个BuilderRobotInvocationHandler类甚至根本没有实现Robot接口。相反,它实现了java.lang.reflect.InvocationHandler,只提供了一个invoke方法。代理对象上的任何方法调用都要通过这一方法进行。观察invoke的主体,我们发现它会检查准备调用的方法的名称。如果这个名称是workOn,第二个参数就切换成一个非破坏性的工具。
然而,我们得到的仍然只是一个具有invoke方法的InvocationHandler,而不是我们真正想要的Robot对象。动态代理真正的魅力要到创建实际的Robot实例时才能反映出来。在源代码的任何地方,我们都没有定义一个Robot包装器或者子类。虽然如此,我们最终仍能获得一个动态创建的类,它通过调用BuilderRobotInvocationHandler的静态方法createBuilderRobot中的代码片断,从而实现了Robot接口,并集成了Builder工具过滤器。
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BuilderRobotInvocationHandler implements InvocationHandler {
private Robot wrapped;
public BuilderRobotInvocationHandler(Robot r) {
wrapped = r;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("workOn".equals(method.getName())) {
args[1] = Tool.RATCHET;
}
return method.invoke(wrapped, args);
}
public static Robot createBuilderRobot(Robot toWrap) {
return (Robot)(Proxy.newProxyInstance(Robot.class.getClassLoader(),
new Class[] {Robot.class},
new BuilderRobotInvocationHandler(toWrap)));
}
public static final void main(String[] args) {
Robot r = createBuilderRobot(new MyRobot());
r.workOn("scrap", Tool.CUTTING_TORCH);
}
}
createBuilderRobot中的代码表面上很复杂,但它的作用其实很简单,就是告诉Proxy类用一个指定的类加载器来动态创建一个对象,该对象要实现指定的接口(本例为Robot),并用提供的InvocationHandler来代替传统的方法主体。结果对象在一个instanceof Robot测试中返回true,并提供了在实现了Robot接口的任何类中都能找到的方法。
有趣的是,在BuilderRobotInvocationHandler类的invoke方法中,完全不存在对Robot接口的引用。InvocationHandlers并不是它们向其提供了“代理方法实现”的接口所专用的,你完全可以写一个InvocationHandler,并将其作为众多代理类的后端来使用。
但在本例中,我们以构造函数参数的形式,为BuilderRobotInvocationHandler提供了RobotInterface的另一个实例。代理Robot实例上的任何方法调用最终都由BuilderRobotInvocationHandler委托给这个“包装的”Robot。但是,虽然这是最常见的设计,但你必须了解,InvocationHandler不一定非要委托给被代理的接口的另一个实例。事实上,InvocationHandler完全能自行提供方法主体,而无需一个委托目标。
最后要注意,如果Robot接口中发生改变,那么BuilderRobotInvocationHandler中的invoke方法将反应迟钝。例如,假定workOn方法被重命名,那么非破坏性工具陷阱会悄悄地失败,这时的BuilderRobots就有可能造成损害。较容易检测、但却不一定会造成问题的是workOn方法的重载版本。如果方法具有相同的名称,但使用一个不同的参数列表,就可能在运行时造成一个ClassCastException或者ArrayIndexOutOfBoundsException异常。为此,以下代码给出了一个解决方案,它能生成一个更灵活的BuilderRobotInvocationHandler。在这段代码中,任何时候在任何方法中使用一个工具,这个工具就会被替换成一个非破坏性工具。请试着用子类化处理或者传统的委托来进行试验。
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BuilderRobotInvocationHandler implements InvocationHandler {
private Robot wrapped;
public BuilderRobotInvocationHandler(Robot r) {
wrapped = r;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Class[] paramTypes = method.getParameterTypes();
for (int i=0; i < paramTypes.length; i++) {
if (Tool.class.isAssignableFrom(paramTypes[i])) {
args[i] = Tool.RATCHET;
}
}
return method.invoke(wrapped, args);
}
public static Robot createBuilderRobot(Robot toWrap) {
return (Robot)(Proxy.newProxyInstance(Robot.class.getClassLoader(),
new Class[] {Robot.class},
new BuilderRobotInvocationHandler(toWrap)));
}
public static final void main(String[] args) {
Robot r = createBuilderRobot(new MyRobot());
r.workOn("scrap", Tool.CUTTING_TORCH);
}
}
使用建议
在大多数开发环境中,用工具来取代Robot并不是一种常见的操作。还有其他许多方式可以使用动态代理。它们提供了一个调试层,可方便地记录一个对象上的所有方法调用的具体细节。它们可执行绑定检查,并对方法参数进行验证。在与远程数据源发生冲突的前提下,甚至可用它们将备用的本地测试后端动态地交换出去。如果你采用的是良好的、由接口驱动的设计方案,我个人觉得动态代理的用处肯定要比你想象的多,最终你会叹服于它从容解决许多问题的本事!
假如没有动态代理
深入探索动态代理类之前,先来看看在某些情况下,假如没有动态代理类会是什么样子:
public interface Robot {
void moveTo(int x, int y);
void workOn(Project p, Tool t);
}
public class MyRobot implements Robot {
public void moveTo(int x, int y) {
// stuff happens here
}
public void workOn(Project p, Tool t) {
// optionally destructive stuff happens here
}
}
上述代码展示了一个名为Robot的接口,以及该接口的一个名为MyRobot的大致的实现。假定你现在想拦截对MyRobot类发出的方法调用(可能是为了限制一个参数的值)。
public class BuilderRobot implements Robot {
private Robot wrapped;
public BuilderRobot(Robot r) {
wrapped = r;
}
public void moveTo(int x, int y) {
wrapped.moveTo(x, y);
}
public void workOn(Project p, Tool t) {
if (t.isDestructive()) {
t = Tool.RATCHET;
}
wrapped.workOn(p, t);
}
}
一个办法就是使用显式的包装器类,就像上面显示的那样。BuilderRobot类在其构造函数中获取一个Robot,并拦截workOn方法,确保在任何项目中使用的工具都没有破坏性。另外,由于BuilderRobot这一包装器实现了Robot接口,所以凡是能够使用一个Robot的任何地方,都能使用一个BuilderRobot实例。
对于这种包装器风格的BuilderRobot来说,一旦你想修改或扩展Robot接口,它的缺点就会暴露无遗。为Robot接口添加一个方法,就得为BuilderRobot类添加一个包装器方法。为Robot添加10个方法,就得为BuilderRobot添加10个方法。如果BuilderRobot、CrusherRobot、SpeedyRobot和SlowRobot都是Robot包装器类,就必须分别为它们添加10个方法。这显然是效率极差的一种方案。
public class BuilderRobot extends MyRobot {
public void workOn(Project p, Tool t) {
if (t.isDestructive()) {
t = Tool.RATCHET;
}
super.workOn(p, t);
}
}
上述代码是对 BuilderRobot进行编程的另一种方式。注意BuilderRobot变成了MyRobot的一个子类。这样可解决在第2段代码的包装器方案中出现的问题。也就是说,修改Robot接口不必修改BuilderRobot。但这又产生了一个新问题:只有MyRobot对象才能是BuilderRobot。而在此之前,实现了Robot接口的任何对象都可以成为一个BuilderRobot。现在,由Java施加的“线性类出身限制”(linear class parentage restrictions)禁止我们将任意Robot(ArbitraryRobot)变成一个BuilderRobot。
动态代理也有限制
动态代理则综合了以上两种方案的优点。使用动态代理,你创建的包装器类不要求为所有方法都使用显式的包装器,创建的子类也不要求具有严格的出身,两者方法可任选一种你认为最好的。但是,动态代理仍然有一个限制。当你使用动态代理时,要包装/扩展的对象必须实现一个接口,该接口定义了准备在包装器中使用的所有方法。这一限制的宗旨是鼓励良好的设计,而不是为你带来更多的麻烦。根据经验,每个类都至少应该实现一个接口(nonconstant接口)。良好的接口用法不仅使动态代理成为可能,还有利于程序的模块化。
使用动态代理
下面的代码演示了用动态代理来创建一个BuilderRobot时所必需的类。注意我们创建的这个BuilderRobotInvocationHandler类甚至根本没有实现Robot接口。相反,它实现了java.lang.reflect.InvocationHandler,只提供了一个invoke方法。代理对象上的任何方法调用都要通过这一方法进行。观察invoke的主体,我们发现它会检查准备调用的方法的名称。如果这个名称是workOn,第二个参数就切换成一个非破坏性的工具。
然而,我们得到的仍然只是一个具有invoke方法的InvocationHandler,而不是我们真正想要的Robot对象。动态代理真正的魅力要到创建实际的Robot实例时才能反映出来。在源代码的任何地方,我们都没有定义一个Robot包装器或者子类。虽然如此,我们最终仍能获得一个动态创建的类,它通过调用BuilderRobotInvocationHandler的静态方法createBuilderRobot中的代码片断,从而实现了Robot接口,并集成了Builder工具过滤器。
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BuilderRobotInvocationHandler implements InvocationHandler {
private Robot wrapped;
public BuilderRobotInvocationHandler(Robot r) {
wrapped = r;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("workOn".equals(method.getName())) {
args[1] = Tool.RATCHET;
}
return method.invoke(wrapped, args);
}
public static Robot createBuilderRobot(Robot toWrap) {
return (Robot)(Proxy.newProxyInstance(Robot.class.getClassLoader(),
new Class[] {Robot.class},
new BuilderRobotInvocationHandler(toWrap)));
}
public static final void main(String[] args) {
Robot r = createBuilderRobot(new MyRobot());
r.workOn("scrap", Tool.CUTTING_TORCH);
}
}
createBuilderRobot中的代码表面上很复杂,但它的作用其实很简单,就是告诉Proxy类用一个指定的类加载器来动态创建一个对象,该对象要实现指定的接口(本例为Robot),并用提供的InvocationHandler来代替传统的方法主体。结果对象在一个instanceof Robot测试中返回true,并提供了在实现了Robot接口的任何类中都能找到的方法。
有趣的是,在BuilderRobotInvocationHandler类的invoke方法中,完全不存在对Robot接口的引用。InvocationHandlers并不是它们向其提供了“代理方法实现”的接口所专用的,你完全可以写一个InvocationHandler,并将其作为众多代理类的后端来使用。
但在本例中,我们以构造函数参数的形式,为BuilderRobotInvocationHandler提供了RobotInterface的另一个实例。代理Robot实例上的任何方法调用最终都由BuilderRobotInvocationHandler委托给这个“包装的”Robot。但是,虽然这是最常见的设计,但你必须了解,InvocationHandler不一定非要委托给被代理的接口的另一个实例。事实上,InvocationHandler完全能自行提供方法主体,而无需一个委托目标。
最后要注意,如果Robot接口中发生改变,那么BuilderRobotInvocationHandler中的invoke方法将反应迟钝。例如,假定workOn方法被重命名,那么非破坏性工具陷阱会悄悄地失败,这时的BuilderRobots就有可能造成损害。较容易检测、但却不一定会造成问题的是workOn方法的重载版本。如果方法具有相同的名称,但使用一个不同的参数列表,就可能在运行时造成一个ClassCastException或者ArrayIndexOutOfBoundsException异常。为此,以下代码给出了一个解决方案,它能生成一个更灵活的BuilderRobotInvocationHandler。在这段代码中,任何时候在任何方法中使用一个工具,这个工具就会被替换成一个非破坏性工具。请试着用子类化处理或者传统的委托来进行试验。
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BuilderRobotInvocationHandler implements InvocationHandler {
private Robot wrapped;
public BuilderRobotInvocationHandler(Robot r) {
wrapped = r;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Class[] paramTypes = method.getParameterTypes();
for (int i=0; i < paramTypes.length; i++) {
if (Tool.class.isAssignableFrom(paramTypes[i])) {
args[i] = Tool.RATCHET;
}
}
return method.invoke(wrapped, args);
}
public static Robot createBuilderRobot(Robot toWrap) {
return (Robot)(Proxy.newProxyInstance(Robot.class.getClassLoader(),
new Class[] {Robot.class},
new BuilderRobotInvocationHandler(toWrap)));
}
public static final void main(String[] args) {
Robot r = createBuilderRobot(new MyRobot());
r.workOn("scrap", Tool.CUTTING_TORCH);
}
}
使用建议
在大多数开发环境中,用工具来取代Robot并不是一种常见的操作。还有其他许多方式可以使用动态代理。它们提供了一个调试层,可方便地记录一个对象上的所有方法调用的具体细节。它们可执行绑定检查,并对方法参数进行验证。在与远程数据源发生冲突的前提下,甚至可用它们将备用的本地测试后端动态地交换出去。如果你采用的是良好的、由接口驱动的设计方案,我个人觉得动态代理的用处肯定要比你想象的多,最终你会叹服于它从容解决许多问题的本事!
发表评论
-
JAVA 线程
2011-01-11 10:32 1290我们可以在计算机上运 ... -
WeakReference
2011-01-11 09:02 2381reachable, the following happen ... -
Java的多线程机制
2010-08-25 23:59 19090程序、进程和线程: ... -
Why would a static inner interface be used in Java?
2010-07-22 11:01 1535Q:I have just found a static in ... -
java中的深拷贝和浅拷贝
2010-07-22 10:58 1473做项目时,可能会碰到这样的一个问题,就是需要把一个对象的属性完 ... -
JAVA 反射
2010-07-22 10:41 1511反射:Class c = Class.forName (&qu ... -
Thinking in java inner classes
2010-07-21 09:44 1185Thinking in java inner cla ... -
1Java 的多重继承与内部类
2010-07-21 09:38 2412<!-- @pa ... -
java插入排序算法
2010-06-29 09:52 1410插入排序算法策略:排序值列中的前2个值,并在必要时交换它们。在 ... -
Java中的volatile关键字
2010-06-12 10:00 1211Java中的volatile关键字 ... -
java 数组排序后,倒过来
2010-01-29 20:11 2778public int[] sort() ... -
用java获取文件夹的大小
2010-01-29 20:09 9539用java获取文件夹的大小 ... -
JAVA移位运算符
2009-12-03 15:50 35650移位运算符就是在二进 ... -
java二进制,字节数组,字符,十六进制,BCD编码转换
2009-12-03 15:48 7426java二进制,字节数组,字符,十六进制,BCD编码转换 ... -
Java内存泄露
2009-02-02 12:02 1912一、问题的提出 Java的一个重要优点就是通过垃圾收集器(Ga ... -
Java 的反射机制基本理解
2008-12-04 17:55 1624Java 的反射机制是使其具有动态特性的非常关键的一种机制,也 ... -
JAVA基础(多线程Thread和Runnable的使用区别
2008-12-04 15:03 44261Runnable是Thread的接口,在大多数情况下“推荐用接 ... -
java解构造器
2008-11-27 10:14 1232解构造器 构造器和方法的区别 摘要 要学习Java,你 ... -
equalsbuilder 示例
2008-11-27 09:32 18861.判断是否为空(null),是则false 2.判断是否 ... -
InputStream,Reader,byte[]数据或字符串的内容拷贝到OutputStream或
2008-11-24 12:54 9146007-07-18 妙用Commons良药<一> ...
相关推荐
在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...
- 框架:Spring的AOP、MyBatis的Mapper等大量使用动态代理。 7. **优缺点** 优点:灵活性高,可以在不修改原有代码的情况下扩展功能;减少代码重复,提高代码复用。 缺点:性能损耗,因为涉及到额外的反射和接口...
这些代码可能涉及到如何创建分页对象,如何与数据库交互获取分页数据,以及如何在AOP中使用动态代理进行拦截和处理。 总的来说,Java分页、动态代理和AOP是Java开发中的关键技术,它们能帮助我们构建出更加高效、可...
它通过实现`java.lang.reflect.InvocationHandler`接口并使用`java.lang.reflect.Proxy`类来创建代理对象。`InvocationHandler`接口定义了一个方法`invoke()`,当通过代理对象调用任何方法时,实际上都会调用这个...
在实际应用中,动态代理和反射可以结合使用,例如,我们可以创建一个动态代理来包装`DatagramSocket`类的实例,这样在每次发送和接收数据时,都可以利用反射调用原始方法,并通过代理类添加额外的功能,如错误处理、...
Java中的动态代理是一种强大的设计模式,它允许我们在运行时创建具有特定行为的代理对象,这些对象可以对原对象的方法调用进行拦截、增强或包装。Spring AOP(面向切面编程)是Spring框架的一部分,它利用了Java的...
在这个“包含静态代理和动态代理demo代码”的压缩包中,我们可能会看到两种常见的Java代理实现方式的示例:静态代理和动态代理。 首先,我们来详细讲解静态代理。在静态代理中,代理类和真实类(目标类)都是在编译...
在这个“java代理实例”中,我们将会深入探讨Java动态代理(Dynamic Proxy)以及静态代理(Static Proxy)的概念,这两种方法都是实现代理模式的关键。 一、Java动态代理 动态代理是Java内置的机制,主要依赖于`...
总的来说,Java反射和动态代理提供了一种强大的工具,允许我们在运行时探索和操作类的结构,实现代码的动态扩展和灵活控制。这对于构建可扩展、可维护的系统至关重要,尤其是在需要实现复杂逻辑如日志记录、性能监控...
Spring AOP使用动态代理来实现切面功能。它可以基于JDK动态代理(如果目标类实现了接口)或CGLIB(如果目标类没有接口)。Spring AOP代理可以在方法调用前后自动插入切面逻辑,如事务管理、性能监控等。 5. **代理...
ASM可以被用来创建Java代理、实现元编程、甚至深入到Java虚拟机(JVM)层面进行性能优化。在Java开发中,ASM库允许我们直接操作字节码,这对于理解和实践AOP(面向切面编程)的概念尤其有用,就像Spring框架中的AOP...
Java动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建具有特定接口的代理对象,这些代理对象可以自动地拦截并处理方法调用。动态代理机制在很多场景下都发挥着关键作用,比如AOP(面向切面编程)、...
在"ProxySimple"这个例子中,可能包含了一个简单的代理实现,比如创建了一个代理类来包装一个实际的业务对象。代理类可能会在执行业务方法前后加入一些附加操作,例如记录日志、验证权限等。具体实现细节需要查看源...
### JAVA真实包装项目经验——二手车项目面试知识点梳理 #### 一、项目开发流程 1. **项目立项**:项目的启动阶段,确定项目的目标、范围、预算等。 2. **需求分析会议**: - 项目经理、研发部和产品部共同参与。 ...
这个"动态代理工程"示例可能包含了一个或多个Java源文件,展示了如何使用Java的动态代理机制来增强或扩展已有对象的行为。 动态代理主要通过两个核心类实现:`java.lang.reflect.Proxy` 和 `java.lang.reflect....
1. **JDK动态代理**:基于Java的反射机制,通过实现`java.lang.reflect.InvocationHandler`接口并调用`java.lang.reflect.Proxy`类的`newProxyInstance()`方法来创建代理对象。`InvocationHandler`接口定义了一个`...
学生提问:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 141 5.5.2 构造器的重载 142 学生提问:为什么要用this来调用另一个重载的构造器?我把另一个构造器里的代码复制、粘贴到这个构造器...
2. **添加Java库到PB项目**:将生成的Java代理类JAR文件添加到PB项目的类路径中,以便PB可以识别并加载这些类。 3. **创建PB数据窗口**:在PB中创建一个数据窗口,用于包装Web服务的调用。数据窗口可以映射到Web...
2. 动态代理:JDK6引入了`java.lang.reflect.Proxy`类,允许动态创建代理对象,实现接口方法的调用。 3. 注解(Annotation):增强了代码的元数据功能,可以用于编译时检查、运行时处理等。 4. 自动装箱与拆箱:简化...