这一阵子在做一个seasar2的项目,看到s2的dao,感觉非常神奇,不需要实例化dao,只要有interface和相应的sql就能行了?!
然后最近又在读Bruce Eckel的《Thinking in Patterns with java》中文版,看到一个动态代理模式,只要有一个interface,然后靠Proxy进行动态代理就可以不实例化地代理interface,然后又忽然想到s2的dao,估计s2dao就是用动态代理来实现的吧。
关于java的动态代理,Bruce Eckel的《Thinking in Java》有一个说明得很详细的章节,中文版的第四版在14.7节,自337页起。里面的示例代码写得真是太好了。
在这里摘录《Thinking in Patterns with java》中文版中,关于动态代理模式的一段话,我觉得很有道理。
读者 Andrea 写道:
『除了最后一个练习,我觉得你给出的上面几个练习都不咋的。我更愿意把Invocation handler 看成是能和被代理对象正交的 (orthogonal) 东东。
换句话说,invocation handler 的实现应该是和动态创建的代理对象所提供的那些接口完全无关的。也就是说,一旦 invocation handler 写好之后,你就可以把它用于任何暴露接口的类,甚至是那些晚于 invocation handler 出现的类和接口。
这就是我为什么要说 invocation handler 所提供的服务是和被代理对象正交的(orthognal)。Rickard 在他的 SmartWorld 例子里给出了几个 handler,其中我最喜欢的是那个调用-重试(call-retry)handler。它首先调用那个(被代理的)实际对象,如果调用产生异常或者等待超时,就重试三次。如果这三次都失败了,那就返回一个异常。这个 Handler 可以被用于任何一个类。
那个 handler 的实现相对于你这里讲的来说过于复杂了,我用这个例子仅仅是想说明我所指的正交(orthogonal)服务到底是什么意思。
您所给出的那几个练习,在我看来,唯一适合用动态代理实现的就是最后那个用XML-RPC 与对象通信的那个练习。因为你所使用的用以分发消息的机制(指 XML-RPC)是和你想要建立通信的那个对象完全正交的。』
然后今天早上去看了s2dao的source,才知道s2dao并不是用动态代理,而是用javassist动态代码注入来实现的。