- 浏览: 2105913 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
无心流泪wan:
private static final Log log = ...
log4j Category.callAppenders Block -
yjxa901:
博主好: http://www.java.net/down ...
jdk debug -
aptech406328627:
大神,请接收我的膜拜吧,纠结了两天的问题,就这么让你给解决了 ...
java.lang.reflect.MalformedParameterizedTypeException -
xukunddp:
谢谢1楼,我也遇到,搞定了
java.lang.reflect.MalformedParameterizedTypeException -
di1984HIT:
学习了!!!!
jvmstat hsperfdata java.io.tmpdir
转载自:http://www.javaresearch.org/article/89240.htm
Dynamic Proxy 在 Java RMI 中的应用
Forest Hou
2000年9月6
日,Rickard Oberg (Jboss 的主要作者之一) 在RMI-USERS 邮件组贴了一个标题
为 "HOWTO: Use Dynamic Proxies as RMI stubs + HOWTO: Export dynammic proxies as RMI objects" 的
贴子, 展示了Dynamic Proxy 如何用在Java RMI 中。利用这项技术,程序员可以在RMI中加入各种服
务 (Authentication, Logging, Transaction 等等) 而不改变RMI的 interface。这一技术是
JBoss实现EJB模型的关键。本文详细介绍了这一技术。Rickard曾用"SmartWorld"展示这一技术,并放在他的网站上供下载。遗憾的是
我们今天已经无法看到SmallWorld了。笔者调通了Rickard帖子中的例子,称之为"SmallWorld",在本文中讲解。读者可以下载这个
例子。
在RMI中加入Interceptor
我非常喜欢Java RMI。相对于其他的分布式对象模
型 (CORBA, COM) ,RMI 显得很轻,很简单。但是有时候程序员想在RMI中加入各种服务(service)而不改变其
interface,却不是那么简单。"Interceptor"作为一种重要的"Design Pattern"在现代软件技术中非常流行,它通常用来
实现service,因此是实现FrameWork的关键技术之一。
下面是一个非常简单的RMI例子。我要在这个例子上加入Interceptor,用以展现神奇的Dynamic Proxy技术。
//: SmallWorld Interface
public interface SmallWorld extends java.rmi.Remote
{
public static final String NAME = "SmallWorld";
public String hello(int i) throws java.rmi.RemoteException;
}
SmallWorld 是一个简单的RMI interface,其中只定义了一个方法hello()。
//: SmallWorldImpl
import java.rmi.server.*;
import java.rmi.*;
public class SmallWorldImpl extends UnicastRemoteObject implements SmallWorld
{
public SmallWorldImpl() throws RemoteException {
super();
}
public String hello(int i) throws java.rmi.RemoteException
{
System.out.println("In SmallWorldImpl i = " + i);
return ("Hello number=" + i);
}
}
SmallWorldImpl是SmallWorld interface 的实现。这是一个再标准不过的RMI实现,你可以在任何RMI教科书中找到类似的例子。
Client的实现如下:
//: Client
import java.rmi.*;
public class Test
{
public static void main(String[] args)
{
try {
SmallWorld he =(SmallWorld)Naming.lookup(SmallWorld.NAME);
System.out.println(he.hello(4));
System.out.println(he.hello(8));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client首先用RMI Naming Service找到SmallWorld的Stub对象,然后调用它的远程方法"hello()"。
最后是一个简单的Server,它实现一个SmallWorldImpl的实例,然后把它bind到RMI Naming Service上。
//: SimpleServer
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
public class SimpleServer
{
public static void main(String[] args)
{
try {
// Create remote object
SmallWorld server = new SmallWorldImpl();
Registry reg = LocateRegistry.createRegistry(1099);
reg.bind(SmallWorld.NAME, server);
} catch (Exception e) {
e.printStackTrace();
}
}
}
大
多数的RMI应用程序都是基于上面的模型实现的。可是这一模型很难加入security, log 等服务。因为一个正式的RMI应用系统中的远程对象和
远程数量非常巨大,而且时常处于变动之中,给每个方法(Method)加上个数不定的服务(service)是不现实的。笔者曾参预的一个项目曾有很不错
的设想:系统欲实现session管理,因此引入了session key。问题是每次远程调用都要传递session key,每一个method都要
检查session key,相信没有程序员愿意这么做。结果当然可想而知啦。
实际上,每一个不错的FrameWork都会采用类似下面的实现方案:
这
里Interceptors用来实现各种可插入的service,例如
authentication, access controller, logging, performance metrics, transaction 等
等。这种方案的关键在于各种service是可以配置的,它们和远程方法相对独立。因此写远程对象的程序员不必为代码中时不时要插入各种service的
调用而烦恼,因为这些service已经在进入远程对象之前被执行了。
对于RMI,我们要求程序员的代码不改变或者极少改变,而
service provider能加入各种interceptor。这可是一个很美妙的梦,Rickard Oberg经过不懈的探索终于实现了这一梦
想。如今该技术已经成为Jboss的两大核心技术之一(另一核心技术是JMX) 。要理解该技术你必须稍微深入了解一下RMI的实
现,Java Dynamic Proxy,ClassLoader,以及Object Serialization。这里我只是讲这些技术
在RMI Stub中的应用,如果读者觉得困惑或者想吃透这些技术,请参阅本文所列参考资料。Rickard Oberg几乎每行代码都值得仔细推敲,笔者刚开始几乎什么都看不明白,遇到不懂就查阅相关资料,这才弄明白了其中的道理。:-)
深入Java RMI : RemoteObject, RemoteStub, RemoteRef, exportObject
其
实要想深入了解RMI是很困难的。只要看一看RMI的几个package包含多少class, interface, exception,你就明白了。
相比之下,EJB包含的东西要少的多,而且interface之间的关系也非常简单明了。我现在感兴趣的是:程序员写的远程对象
(SmallWorldImpl,不同于RemoteObject class,下面我用"远程对象"表示这一级别的class,而
用"RemoteObject"表示java RMI中的class) 实现时包含哪几部份?RMI是怎样创建它们的?
多数远程对象实现时都继
承了UnicastRemoteObject,通过javac编译生成class文件后,再用rmic编译该class文件生成相应的Stub和
Skeleton class。Stub class是该远程对象的远程代理,用于发出远程调用;Skeleton和远程对象处于同一地
址,Skeleton用于接收,转发"调用"到该对象。
但是Skeleton并不是必需的。如果你在用rmic时加上"-v1.2" 的选项,生成的是Java2标准的Stub class ,这时没有Skeleton class。
上述关键部份用下面的UML图表示:
RemoteRef是RemoteObject的远程handle,它的作用体现在RemoteStub中。Client端的远程调用都是通过RemoteRef实行的。你可以用下面的命令生成SmallWorldImpl_Stub的源代码:
rmic -keep -v1.2 SmallWorldImpl
其中hello()方法是这样实现的:
// implementation of hello(int)
public java.lang.String hello(int $param_int_1) throws java.rmi.RemoteException
{
try {
Object $result = ref.invoke(this, $method_hello_0,
new java.lang.Object[] {new java.lang.Integer($param_int_1)},
-7781462318672951424L);
return ((java.lang.String) $result);
} catch (java.lang.RuntimeException e) {
throw e;
} catch (java.rmi.RemoteException e) {
throw e;
} catch (java.lang.Exception e) {
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
}
}
而RemoteRef的prototype是:
public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception
其中opnum是表示method的hash值,用来作authentication,这里我们不关心。我们将会看到正是该方法的反射性(reflection),使实现client端的interceptor成为可能。
下面我们来看一下Stub在server端的生成过程,以及client发现它的过程。
SmallWorldImpl
的构造方法调用了super()方法,该方法实际调用到UnicastRemoteObject的构造方法,而UnicastRemoteObject的
构造方法将调用exportObject()方法。exportObject试图用SmallWorldImpl的ClassLoader加载
SmallWorldImpl_Stub class并生成它的实例,也就是:
// assume obj = SmallWorldImpl
String name = obj.getClass().getName();
Class c = Class.forName(name + “_Stub”, false, obj.getClass().getClassLoader());
RemoteStub stub = (RemoteStub)c.newInstance();
然后把它发布到指定的socket上,这时候该远程对象就可以使用了。为了client端查找方便,server应该用Naming Service把这个Stub实例公布出来,这就是Registry.bind()起的作用。
java.rmi.registry.Registry
public void bind(String name, Remote object);
该方法把SmallWorldImpl_Stub实例序列化(Serialization) ,再把序列化的object发送到Naming Server上去。
Server也可以直接调用UnicastRemoteObject的exportObject()方法公布远程对象。
Client端调用Registry.lookup()方法找到SmallWorldImpl_Stub的实例,然后就可以调用其中的远程方法了。
因
此,我们必须实现自己的Stub,让它实现远程对象的所有远程方法,在调用RemoteRef的invoke()方法之前先通过client端的一系列
interceptors;在server端进入实际的被调用方法之前也要通过一系列interceptors,所有的interceptor都说"可
以"才进入被调用方法。
JDK1.3里出现的Dynamic Proxy使得这一设想能够简单地实现。
Dynamic Proxy 工作原理
Dynamic Proxy是由两个class实现的:java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler,后者是一个接口。
所
谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class
就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个
Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工
作。:-)
java.lang.reflect.Proxy中的重要方法如下:
public static Class getProxyClass(ClassLoader loader, Class[] interfaces);
该
方法返回一个Dynamic Proxy Class给你,但你必须提供一个ClassLoader和一组interface定义给它。记住:每一个
Class在JVM中都有一个对应的ClassLoader,这个Proxy就说这个loader是它的ClassLoader,它还说它实现了这些
interface。
protected Proxy(InvocationHandler handler);
返回给你的Dynamic Proxy有这样一个构造方法,而且你只能用它生成实例。你对那些interface中所有方法的调用(基于该实例) 都会传到这个handler中。
更简单的方法是一步生成Dynamic Proxy的实例:
public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h) throws IllegalArgumentException;
这个方法包含了上面两个方法的所有参数,而且意义相同。
java.lang.reflect.InvocationHandler中只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args);
对于Dynamic Proxy实例中方法的调用都将调到这个方法。其中proxy正是那个Dynamic Proxy实例,而method,args是被调用方法和参数。
比较java.lang.reflect.Method中的这个方法:
public Object invoke(Object obj, Object[] args);
它说的是你现在调用obj实例中的Method.getName()方法,传递的参数是args。
实际上,所有的InvocationHandler都会调用Method中的这一方法,它是到达真正方法的唯一途径。
来看一个实例:
public class Interceptor implements InvocationHander
{
private Object obj;
public InvocationHandler(Object o)
{
obj = o; //保存实例,以备后用
}
public Object invoke(Object proxy, Method method, Object[] args)
{
system.out.println(“Enter interceptor”);
method.invoke(obj, args); //调用真正的方法
}
}
//假设obj是一个SmallWorldImpl的实例
SmallWorld sw =Proxy.newInstance(obj.getClass().getClassLoader(), obj.getClass().getDeclaredClasses(), new Interceptor(obj));
sw.hello(4);
对于hello()的调用首先通过Interceptor的invoke()方法。
java.lang.reflect package是如此重要,以至于任何稍具规模的应用都离不开它。它给java带来巨大的灵活性,但是谁测试过它对系统性能的影响呢?
好
了,我们该看看Rickard Oberg怎么实现他的smart stub了。 DynamicClassLoader我们已经知道
Stub class是通过远程对象(SmallWorldImpl)的ClassLoader加载到JVM中的,而RMI是在远程对象名字之后
加 "_Stub" 字符串形成Stub的class名字的。这里DynamicClassLoader用来加载远程对象的class和Stub的
class:
//: DynamicClassLoader
import java.net.URLClassLoader;
import java.net.URL;
public class DynamicClassLoader extends URLClassLoader
{ // Static
static ThreadLocal currentClass = new ThreadLocal();
public static Class getCurrentClass()
{
return (Class)currentClass.get();
}
// Constructors --------------------------------------------------
public DynamicClassLoader(URL[] urls)
{
super(urls);
}
// Public implementation -----------------------------------------
protected Class findClass(String name) throws ClassNotFoundException
{
if (name.endsWith("_Stub")) {
name = name.substring(0,name.length()-5);
// Get impl
Class cl = loadClass(name);
// Assume that it only implements one remote interface
currentClass.set(cl.getInterfaces()[0]);
return DynamicRemoteStub.class;
} else {
return super.findClass(name);
}
}
}
这个class有两点值得注意:
• DynamicClassLoader
继承了URLClassLoader,大多数用户定制(Customize) 的ClassLoader都继承这个ClassLoader。
DynamicClassLoader只需重载(Overload) findClass()这一个方法。如果欲加载class名字以"_Stub" 结
束,返回DynamicRemoteStub的class;否则让URLClassLoader加载这个class。
• 如果欲加载
class 是Stub class,findClass()要找到对应的远程对象实现的所有remote interface,并且记住它们,因为以后
的DynamicRemoteStub要代理这些interface。对于我们的例子,Stub class 是
SmallWorldImpl_Stub,远程对象是SmallWorldImpl,Remote interface只有一个:SmallWorld。
为了简化问题,代码假设远程对象只实现一个interface而且它就是Remote interface。实际实现时要做一些检查,并有些技巧。
记
住这些Remote interface是一个问题。因为这时DynamicRemoteStub的实例还没有生成,我们没办法传到它里面。这里使用了
ThreadLocal class。ThreadLocal是一个和Thread相关联的变量,它属于一个特定的Thread。因为
DynamicRemoteStub的实例初始化方法仍用这个Thread,它能读出这些interface。
DynamicRemoteStub和DynamicStubHandler
Rickard的DynamicRemoteStub如下:
import java.lang.reflect.Proxy;
import java.io.*;
import java.rmi.server.*;
public class DynamicRemoteStub extends RemoteStub
{
// Constructors --------------------------------------------------
Class cl;
public DynamicRemoteStub(RemoteRef ref)
{
super(ref);
cl = DynamicClassLoader.getCurrentClass();
}
// Serializable implementation -----------------------------------
Object readResolve() throws ObjectStreamException
{
if (cl == null) return this;
DynamicStubHandler stubHandler = new DynamicStubHandler();
Object proxy = Proxy.newProxyInstance(cl.getClassLoader(),
new Class[] { cl },
stubHandler);
stubHandler.setProxy(this);
cl = null;
return proxy;
}
}
这里的关键代码在于readResolve()方法。java.io.Serializable API 文档说:
Classes that need to designate a replacement when an instance of it is read from the stream should implement this special method with the exact signature.
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
就
是说一个class如果实现了java.io.Serializable interface 并且实现了这个readResolve方法,那么这个对象
在序列化(Serialization) 之后,被读出还原时,系统要执行这个方法,执行的结果是序列化的对象变成了另一个对象!
对应的方法是writeReplace(),它是在序列化写入流(stream) 时替换成新的对象。
所
以,这里DynamicRemoteStub被RMI序列化并传到client端时变成了一个新的对象,它是一个Dynamic Proxy。这个
Proxy实现了RemoteObject的所有Remote方法,而它的handler是一个DynamicStubHandler实例。
所以在client端的所有远程调用都会由这个Proxy传递到DynamicStubHandler中去。
DynamicStubHandler主要部分是那个invoke()方法:
public class DynamicStubHandler
implements InvocationHandler, java.io.Serializable
{
RemoteStub stub;
// Public --------------------------------------------------------
public void setProxy(RemoteStub stub)
{
this.stub = stub;
}
// InvocationHandler implementation ------------------------------
public Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
{
System.out.println("DynamicStubHandler!");
return stub.getRef().invoke(stub, method, args, getHash(method));
}
}
我
们已经知道client端的远程调用最终要绕到RemoteRef里,而RemoteRef是DynamicRemoteStub的成员,所以
DynamicRemoteStub在生成这个DynamicStubHandler实例后要调用它的setProxy()方法把它自己传入,以便后者能
找到这个RemoteRef。
这个invoke()方法主要是调用RemoteRef的invoke()方法,计算Hash值的方法很繁琐,但它和本文没太大关系。
我们终于可以在client端插入各种interceptor了。这里只打印了一句话验证这一点。
那么server端呢? 如果我们不作修改,它将直接调到SmallWorldImpl的方法里。所以我们还要在server端加入interceptor。
新Server的实现
新Server的简单实现如下:
import java.lang.reflect.*;
import java.
io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
public class SimpleServer
{
public static void main(String[] args)
{
try {
// Create remote object
URLClassLoader cl = new DynamicClassLoader(new URL[] { new
File("demo").toURL() });
Remote server = (Remote)cl.loadClass("SmallWorldImpl").newInstance();
// it should be DynamicRemoteStub
System.out.println("StubObject is: " +
RemoteObject.toStub((RemoteObject)server).getClass());
// add log proxy to the remote object
server = (Remote)Proxy.newProxyInstance(server.getClass().getClassLoader(),
new Class[] { SmallWorld.class },
new LogProxy(server));
// add performance proxy to the remote object
server = (Remote)Proxy.newProxyInstance(server.getClass().getClassLoader(),
new Class[] { SmallWorld.class },
new PerformanceProxy(server));
UnicastRemoteObject.exportObject(server);
Registry reg = LocateRegistry.createRegistry(1099);
reg.bind(SmallWorld.NAME, server);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Server首先创建一个DynamicClassLoader的实例,然后用它加载SmallWorldImpl class 并创建它的实例,虽然这时一个SmallWorldImpl的Stub对象会被RMI创立,我们却不会去用它。
然
后Server创建了一个针对SmallWorldImpl的Dynamic Proxy,其handler是LogProxy实例,用以模仿
Log interceptor。再其后创建针对Dynamic Proxy的Dynamic Proxy,其handler是
PerformanceProxy实例。
LogProxy的代码如下:
import java.lang.reflect.*;
public class LogProxy implements InvocationHandler
{
Object obj;
public LogProxy(Object o)
{
obj = o;
}
// InvocationHandler implementation ------------------------------
public Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
{
System.out.println("Invoke LogProxy");
return method.invoke(obj, args);
}
}
注意它是怎么向下一个interceptor或RemoteObject传递调用的。
这样,从client端来调用要经过如下途径到达RemoteObje
ct:
PerformanceProxy --> LogProxy --> SmallWorldImpl
Server 最
后把这个Dynamic Proxy 公布(用UnicastRemoteObject.exportObject) ,然后用
Registry.bind() bind到Naming Server上,client 就可以找到它并用它了。而client端的代码根本不用改
变。
注意Server的代码完全可以做到与SmallWorld无关。它的信息完全可以从配置文件中读出。想一下Application Server是不是这样实现的呢?
结束语
这样我们就明白了Dynamic Proxy 在RMI Stub中的应用。我们可以用这一技术往系统中加入许多有趣的interceptor,甚至loadbalance也用它实现。
其
实,该技术是JBoss的基石。JBoss对这一技术的应用更加规范化,专门创建了Interceptor interface,并且每个
Enterprise Bean的Interceptor都是可以配置的。这样的系统灵活性之大,在以前难以想象。而今用java 的
reflect package又能做出多少新东西呢?
参考资料:
1. Rickard Oberg "HOWTO: Use Dynamic Proxies as RMI stubs + HOWTO: Export dynamic proxies as RMI objects"
2. "Dynamic Proxy Classes"
3. Christoph G. Jung "Classloaders Revisited: Hotdeploy"
发表评论
-
groovy shell 安全
2017-01-18 11:29 1202groovy 可以动态执行代码,但是我们也想他在一定的沙箱中 ... -
eclipse 插件
2016-11-17 12:00 609eclipse remote editor https: ... -
java method signature
2013-08-12 21:07 2718case 'B': _type = T_BYT ... -
eclipse显示GC的按钮
2013-06-18 19:32 4334同事说idea的一个比较亮的功能是可以手动去GC,然后机器 ... -
好用的maven插件收集
2013-02-22 10:40 13491:Maven Shade Plugin(把所有jar打到一 ... -
查看JVM Flags
2013-01-09 14:22 1334-XX:+PrintFlagsFinal Jav ... -
开源的好用JVM问题排查工具
2013-01-08 09:45 1860TProfiler https://github.com/ ... -
java ocr
2013-01-04 13:06 3019java OCR相关的资料记录 Clara OC ... -
eclipse ast
2012-12-23 22:36 1012Eclipse JDT - Abstract Syntax ... -
正则生成器
2012-12-23 22:24 977能够依据普通文本给出可能的正则组合 http://ww ... -
Kilim
2012-12-14 23:40 1109Java 开发 2.0: Kilim 简介 h ... -
IO Design Patterns Reactor VS Proactor
2012-11-13 01:34 15081:两种高性能I/O设计模式(Reactor/Proactor ... -
antlr
2012-11-13 00:36 12181:使用 Antlr 开发领域语言 http://www.i ... -
java singalException
2012-11-12 21:39 981之前看到毕大师一封关于异常多造成的cpu us很高的分析邮件, ... -
log4j Category.callAppenders Block
2012-11-06 17:01 10107经常在高并发下就遇到log4j用错引起的线程block住的问题 ... -
Troubleshooting JDK
2012-10-26 14:13 1522收集整理下JDK自带的关于 Troubleshooting 的 ... -
JavaOne 2011 Content Catalog
2012-10-14 17:12 1168上一篇讲javaone 2012,这次找了下2011的资料。 ... -
JavaOne 2012 Content Catalog
2012-10-13 16:07 1309转载自:http://marxsoftware.blogspo ... -
Memory usage of Java
2012-10-01 17:30 1218用JDK自带的api计算size,每次都会有个多余的12,看了 ... -
GC roots
2012-10-01 17:07 18501:GC roots http://www.yourkit. ...
相关推荐
Java Remote Method Invocation (RMI) 是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,实现远程方法调用。本压缩包文件"rmi-code"包含了一个完整的RMI测试代码示例,适合在Linux和...
在Java中,动态代理主要依赖于两个接口:`java.lang.reflect.InvocationHandler` 和 `java.lang.reflect.Proxy`。 `InvocationHandler` 接口定义了一个方法 `invoke()`,该方法会在代理对象的方法被调用时执行。...
在Java编程中,动态代理(Dynamic Proxy)是一种强大的设计模式,它允许我们在运行时创建具有特定接口的新对象。Java的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口...
3. 在客户端代码`TestHelloClient.java`中,使用`javax.xml.rpc.ServiceFactory`从WSDL URL创建服务代理,然后通过调用接口方法来访问Web服务。 通过以上步骤,你可以了解Java WebService的基本概念和实现方式。 ...
在Java中,动态代理主要通过两个类来实现:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。`Proxy` 类用于创建动态代理实例,而 `InvocationHandler` 接口则定义了当调用代理对象的方法时应...
JDK动态代理,全称为Java Dynamic Proxy,是Java标准库提供的一种强大且灵活的机制,允许我们在运行时创建代理类来实现指定的接口。这种机制主要用于实现AOP(面向切面编程)或为已有接口提供额外的功能,如日志、...
* Java EE 5 中,使用标注(annotation)减少了 Web Services 的代码量与部署工作:在 Java EE 5 中,可以使用标注(annotation)来减少 Web Services 的代码量与部署工作,从而简化WebService 的开发和部署过程。
在当今高度互联的世界中,Web服务扮演着连接不同系统、平台和应用程序的重要角色。Java作为一种广泛使用的编程语言,在开发可互操作的Web服务方面拥有强大的能力。本文将详细介绍如何通过三个简单的步骤将现有的Java...
在本文中,我们将重点讨论Web Service的重要概念,特别是与 Axis 框架相关的开发方法,包括Dynamic Invocation Interface (DII) 和 Dynamic Proxy 方式。 ### 1. Web Service基本概念 Web Service通过使用XML(可...
在Java编程中,反射和动态代理是两个非常重要的高级特性,它们为程序提供了更大的灵活性和扩展性。这篇学习笔记主要关注动态代理部分,虽然没有提供具体的压缩包文件内容,但根据标题和描述,我们可以深入探讨这两个...
在实际应用中,Java WebService可以用于实现跨平台的数据交换、系统集成或者作为API供其他应用调用。通过动态调用接口(DII)和动态代理,开发人员可以灵活地创建和消费Web服务,而无需过多关注底层的通信细节。了解...
在这个应用程序中,被创建的 FactoryInstance 实际对象是 SpringFactoryInstance; FactoryInstance 的 lookup() 方法被调用,在 SpringFactoryInstance 中,首先查找 Spring 容器,然后,通过 Bean 的 ID 查找 ...
在这个应用程序中,被创建的 FactoryInstance 实际对象是 SpringFactoryInstance; FactoryInstance 的 lookup() 方法被调用,在 SpringFactoryInstance 中,首先查找 Spring 容器,然后,通过 Bean 的 ID 查找 ...
5. 动态代理(Dynamic Proxy):提供了一种创建动态实现指定接口的对象的机制,常用于AOP(面向切面编程)。 四、其他重要组件 1. Swing GUI:提供了丰富的组件和布局管理器,用于构建桌面应用程序。 2. Applet:...
- **Apache Axis简介**:Apache Axis是Apache组织提供的一个开源项目,用于在Java环境中实现WebService技术规范。它支持SOAP协议,并提供了多种方式来发布和访问WebService。 - **环境准备**: - **J2SE SDK**: ...
Java中的反射机制是一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法等对象。在Java 1.5引入的反射API使得开发者可以在编译期未知的情况下,动态地获取类的信息并执行相关操作。以下将详细介绍...
动态代理(Dynamic Proxy)是一种设计模式,允许在运行时动态地创建一个实现一组接口的代理对象。在久其移动框架中,动态代理主要用于实现AOP等功能。 **工作原理:** - **生成代理类:** 根据提供的接口列表,通过`...
Spring AOP部分会介绍AOP的基本概念、Spring中的AOP实现以及与动态代理(Dynamic Proxy)和CGLib等技术的结合使用。 DAO(Data Access Object)支持是Spring提供的数据访问抽象,它封装了数据访问的细节,使得...
本文将详细介绍如何使用Apache Axis创建Web Service,并将重点介绍三种不同的方法:动态调用接口(Dynamic Invocation Interface,DII)、Stubs方式和动态代理(Dynamic Proxy)方式。 #### 二、环境搭建与配置 在...