以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 Java/Eclipse 』  (http://bbs.xml.org.cn/list.asp?boardid=41)
----  [合集] 有没有人在关注Richard的AOP?  (http://bbs.xml.org.cn/dispbbs.asp?boardid=41&rootid=&id=10256)


--  作者:admin
--  发布时间:9/23/2004 12:40:00 AM

--  [合集] 有没有人在关注Richard的AOP?
● [合集] 有没有人在关注Richard的AOP?发信人: oosky (天天), 信区: J2EE
标  题: [合集] 有没有人在关注Richard的AOP?
发信站: BBS 水木清华站 (Mon Mar 29 18:43:40 2004), 站内

【 以下文字转载自 JavaClub 讨论区 】
发信人: oosky (天天), 信区: JavaClub
标  题: [合集] 有没有人在关注Richard的AOP?
发信站: BBS 水木清华站 (Mon Mar 29 18:38:19 2004), 站内

☆─────────────────────────────────────☆  
JoyJava (//admire lp~~~) 于  (Tue Nov 12 22:09:18 2002)  提到:

Aspect Oriented Programming,听gty说可以定制一个类似j2ee的平台,呵呵,
richard就是jboss、webwork、xdoclet的项目负责人



☆─────────────────────────────────────☆  
  UltraFool (遥望·遐想·感伤) 于  (Tue Nov 12 22:29:32 2002)  提到:

我最想知道有没有大公司关注它:-)


☆─────────────────────────────────────☆  
cloudor (我要打篮球!!!!!) 于  (Wed Nov 13 08:29:34 2002)  提到:

呵呵,是rickard吧,:Oberg.
这东西现在也是在做吧,有释放出来的资源了么,除了文字的?



☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Wed Nov 13 12:04:21 2002)  提到:

刚才在路上看到程序员杂志上的AOP的java实现
www.aspectj.org


☆─────────────────────────────────────☆  
  cloudor (我要打篮球!!!!!) 于  (Wed Nov 13 13:31:51 2002)  提到:


看到了,心情难以平静了.



☆─────────────────────────────────────☆  
cloudor (大功即将告成!!!) 于  (Wed Nov 13 17:08:30 2002)  提到:


rickard没有参与AspectJ吧。正在看一篇rickard关于aop的文章,
将他自己写的aop和aspectj比较,说自己的虽然没有aspectj的
functional completeness,但拥有更多的flexibility/scalability。
(http://www.projectcast.com/~bungle/rickard_on_aop.html)

AspectJ所具备的优点:
1.拓展java语言使aop成为内建特性
2.在编译时引入一个custom compiler将扩展语言转译为java语言。
3.由于在java语言上拓展,因此可以对java语言使用的各种如
  构造器/方法/字段访问/静态块进行advice(advice的意思就是
  对任意过程进行建议/干涉,对方法调用进行指导)
AspectJ的局限:
1. java是一种非常容易上手的语言,而AOP扩展语言学起来却非常
  困难。
2. 需要特别的编译器。
3. 很难方便地为对象添加advice和extension,需要修改源码。
4. 当一处进行改动时,整个项目源码需要重新编译,重新让编译器
   检查各个advice和extension,因此不适用于大项目的开发。(据说
   将在1.1版本中改善)
5. 没有严格使用interface,因此对象可能会使用你无意中添加的
   feature。
6. 没有引入EJB中管理对象所用的对象代理方法,不便保障更佳的对象粒度与
   提高重用扩展性能。

rickard所追求的是一种集EJB的扩展性和AspectJ的AOP特性与一身的....
(还没取名)




☆─────────────────────────────────────☆  
  cloudor (大功即将告成!!!) 于  (Wed Nov 13 17:32:37 2002)  提到:


说白了,感觉AspectJ其实就是个代码辅助工具,因为各种advice和extension
全是编译时加进去的,生成的class和普通class没有区别,没有办法动态加载
新的advice和extension。



☆─────────────────────────────────────☆  
JoyJava (//admire lp~~~) 于  (Wed Nov 13 17:43:15 2002)  提到:

随着发展,动态都是有可能得,呵呵,aop凸现出来可能是编程思路得转化:

oop讲究对象的重用性,而aop追求的是模块的重用性



☆─────────────────────────────────────☆  
  javarookie (JavaRookie) 于  (Wed Nov 13 18:37:06 2002)  提到:

那酱紫是不是类似于STL啊?
不懂的说




☆─────────────────────────────────────☆  
   cloudor (大功即将告成!!!) 于  (Wed Nov 13 19:10:07 2002)  提到:


看rickard的架式好像就是冲着动态aop去的。其实EJB的部署原理就很象
aop,EJB是把home/localhome interface和remote/local interface这些interface
结合bean class生成一个新的对象,如果引入更多interface和class来创建
一个新对象,可以说这就是aop的extension;而container将EJB的包裹起来
并在调用中插入security/tansaction等interceptor,这其实就是aop的advice。

而创建这么一个新对象的过程完全不需要停下虚拟机,所以ejb真的为
aop做了很好的预备工作,也难怪rickard这么一个ejb专家会自然地把
工作中心从EJB转向aop,因为实在有太多可以利用的东西了。



☆─────────────────────────────────────☆  
JoyJava (//admire lp~~~) 于  (Wed Nov 13 19:51:44 2002)  提到:

我觉得ejb做得预备工作不多,呵呵,component禾container很早就有了嘛
倒是后来rickard做xdoclet,很像aop,呵呵



☆─────────────────────────────────────☆  
  cloudor (大功即将告成!!!) 于  (Wed Nov 13 20:31:25 2002)  提到:


可我觉得xdoclet只是一个标签工具而已,没有动态地为对象添加方法以及
在调用中插入interceptor的功能吧?

而且,当时宣传j3ee也是拿aop取代ejb说事的,所以感觉rickard
的aop平台会是在ejb-container基础上做出来的。



☆─────────────────────────────────────☆  
  JoyJava (//admire lp~~~) 于  (Wed Nov 13 21:01:36 2002)  提到:

我们两个在盲人摸象,等gty能发文了让他谈谈吧


☆─────────────────────────────────────☆  
  bbjj (弱弱) 于  (Wed Nov 13 23:38:26 2002)  提到:

据说可以很好的处理crosscutting,看了一点资料,没有尝试过,不知道具体情况。
不过我觉得从粒度上来说,AOP总看着像是一种辅助的编程方式。不知道前途如何。
呵呵。



☆─────────────────────────────────────☆  
  bbjj (弱弱) 于  (Wed Nov 13 23:40:01 2002)  提到:

我也是这种感觉。至少目前好像就是这样。



☆─────────────────────────────────────☆  
  gty (宜良-丽江-蝴蝶泉) 于  (Thu Nov 14 01:16:53 2002)  提到:

呵呵,xdoclet想要解决的问题,正是aop想要解决的问题,也是OO系统最大的
缺陷。这个缺陷是什么?我也经常遇到,也常常在想,但都不是很清楚。但我
可以把自己不成熟的想法要大概描述一下,希望大家指正:

1. 首先,软件的发展主题是代码复用。这一点恐怕没有疑问。从面向过程到
面向对象,是为了复用;现在从面向对象,到面向aspect(怎么翻译,cloudor?),
也是为了复用。所以AOP是OOP的一种自然进步,不是否定。

2. 面向过程是线性思维,面向对象是平面思维,面向aspect是立体思维(多维?),
这和软件过程的发展有相同之处。起初的软件过程比较强调流程,需求-设计-编码
-测试;后来发觉不是所有的软件系统都是类似流程,例如中国的项目和国外的
项目过程就大相径庭(没有好坏之分,都是解决问题的),因此大家就来归纳,就像
RUP宣传的,大项目应该怎么怎么个流程,内部产品研发应该怎么怎么个流程,归纳
出的对象就类似于Class。大家都实现了“软件开发”这个方法,但流程不同。但过
了一段又不行了,越归纳越多,天南的项目应该怎么做,地北的项目应该怎么做。忽
然有一天,一帮人跳出来号召大家用一个新东西- XP(当然不是微软的东东)。

这帮人倒好,XP中没有规定任何流程(我刚开始看XP时一直有一个疑问不好意思说,
这个东西怎么没有quick start啊),而是列举了一大堆“Practice”,Unit Test,
small Iteration,pair-working...,似乎杂乱无章,是一帮经验主义者。当然,也
许他们确实是,但当我现在结合AOP再来想XP时,却不由得在意识里把它提高了一个
层次,这些Practice都是为了处理某一方面的问题啊,Unit Test是为了验证工作,
small Iteration是为了不断进行集成测试,pair-working是为了提高工作质量,在
传统的开发流程中,需要用到它们的时候尽可以用,宣传最多的例子就是在需求阶
段也可以有Unit Test和small iteration。

3. 总的来说,随着应用系统的日益复杂,OO系统遇到了它的“成长上限”。OO分析
试图将世界用一张UML Class图轧扁到纸上, 但世界分明是N维的,OO必然有克服不
了的困难:

   a. OO的类的复用程度不高。明显的例子是,我们开发的应用层对象往往只能在
自己的某个系统中有用,离开了系统则价值不大。电子商务系统中,Person的属性
不可能包含肝脏,医疗系统中,Person也不需要有makeOrder的方法。

   问题来了,不同领域的系统中,对象如何复用?OO的思路只能是增加对象的属
性和方法,或者是增加新的子类。无论如何,发展的结果,只能是让Person这个
(组)对象变得越来越复杂。别忘了,咱们还有那么多类呢,听说某公司的财务软件
达到了上千个类。

   AOP通过“动态”扩展Class解决了这个问题。AOP系统中,真正属于Class的属
性也许只有一个标签,它的所有方法都可以由Aspect提供。例如Person对象也许
只有它的Id作为识别,生理特性是一个Aspect,商务特性是一个Aspect,e-business
系统中,我们为Person对象增加了商务特性Aspect,医疗系统中,我们为Person对象
增加生理特性Aspect。1 - 3,看来AOP也把问题复杂化了,也许你会想。不,大部分
情况下,这种分离会带来更高的复用水平,Aspect是可以复用的,因为一只狗的定购
过程和人应该不会有很大区别,一只狗的内脏系统和人也不会差到哪儿去。

   当然,Aspect复用可能存在,也可能不存在,但至少提供了一种可能性,这就是
一种进步。而且,根据Rickard Oberg在自己的portal产品项目的实践,Aspect复用
的效果非常惊人!

   b. OO的方法的复用程度不高。明显的例子是,同样一个业务过程,希望突破部
署环境的限制,既可以在Web层实现,又可以在EJB层实现,现有技术下就会遇到很
大困难。例如Transaction,EJB层通常用Container自动控制Transaction,而Web层
只能通过手工调用JTA或者Connection的Transaction控制方法。例如Security,EJB
层可以从SessionContext获取调用者和调用者的角色,因此不需要在方法声明中有
caller参数,而Web层则不能享有这种“优越性”。

   问题又来了,不同领域的,方法如何复用?OO的思路有二:其一,Proxy模式,
保持核心类的方法不变,用一个不同的Proxy适应不同的环境,看过jive源码的人
应该熟悉这个模式(SuperMMX?)。其二:政治手段,技术不能解决,那大家就来开
会,谋求天下一统,于是JSP,EJB,Connector,struts,各种framework满天飞,但
天下大势,分久必合,合久必分,EJB刚出规范,Weblogic就有自己的extension,
Java的天下何时一统,其实很好回答,绝对不可能。

   AOP通过“动态”扩展Method解决了这个问题。AOP系统中,可以为某个类的某
个方法增加advice,即Rickard的AOP中的Interceptor。Interceptor也是可以复用
的。例如Transaction Manager, Security Manager,Persistence Manager,
WebServices Manager都可以以Interceptor的方式实现。

    和J2EE架构的不同之处,在于“动态”二字。何谓动态:
     1).根据需求决定是否调用Interceptor,
     2).根据需求决定调用哪个Interceptor,
     3).根据需求决定如何调用Interceptor,以及各个Interceptor之间的次序。

    AOP的高度灵活的结构,体现了空间概念。它彻底打破了传统代码进入方法体
后的线性执行方式,以及一个类由多个方法构成的平面执行方式。立体化的考虑
问题,很酷吧。

4. 既然面向过程-OO-(包括OA?不知道)都有“难以解决的”缺陷,为什么还会
有黄金时期?因为应用在发展!我们单个程序员所“解决”的问题比起五十年前的
复杂了何止成百上千倍?就和交通工具一样,步行-自行车-地铁,我们花一个小时
可以从清华骑车到阜成门上班,不是很累吧,于是我们敢于到更远的但更有“钱途”
的国贸上班,受不了了,时间要double,幸好城铁修好了,现在也只需要花一个小时。


AOP的实现方法

说了半天,回到本贴开始的主题上,我们谈谈XDoclet和AOP的关系,还有AOP的
实现方法。目前看来,AOP的实现可以分为两条道路:改良和改革。

一、改良派 - “打补丁的方式”
  代表:Xdoclet,AspectJ(!!!)
  主要主张:自动生成代码。环境虽有不同,我自岿然不动,所有和环境相关的代码
都是自动生成!
  新变化的应对手段:扩展新的处理模块和代码模板,例如Xdoclet已经有了针对目
前绝大多数EJB应用服务器的20多个扩展模块。

  评价:
  Xdoclet可以看作是EJB Container的延伸,是我们开发EJB中最实用的一种工具,
可以开发出适应不同应用服务器的EJB。我们目前的项目自动生成的类占到70%,并
且还有通过归纳模式,这个比例还有上升的空间!

  大家一定奇怪AspectJ也落入这个范畴,这是AspectJ虽然扩展出一套AOP语法,
但在编译时却将AOP语言首先转化为OOP(这类似于xdoclet、EJB、C++的代码自动
生成思路)。

  “打补丁”固然能够解决目前的问题,但绝对不是一个“彻底”解决问题的方式。
   1. 这种方式依赖于某种标准的制定,例如EJB Container依赖于EJB,XDoclet依
赖于它制定的文档标签,AspectJ依赖于它的扩展AOP语法。一旦标准发生变化,
甚至被遗弃,世界上会出现很多无意义的代码。

   2. 增加程序员的学习成本,每个补丁都内有天地,请君入瓮。

   3. 补丁打到一定程度,衣服一定会破的。说到底,补丁不是解决问题的根本办法。

二、改革派
  代表:Rickard Oberg的AOP(dreambean.com),
  主要主张:用Dynamic Proxy (JDK1.3中最为革命性的一个特性)和reflection机制实现A
OP

  前提: 在JDK1.3和JDK1.4中,Java的relfection机制性能有了很大提高,这一点从webwo
rk和hibernate
的速度可以体现。
  结果: 可以用最简单的API,用“100%纯Java”实现!
  评价:

  (有空再谈吧,如果有兴趣,建议大家看看下面的一些资料:
     Rickard的weblog : dreambean.com
     一个根据Rickard的思想的AOP实现: nanning.sourceforge.net
     两个依赖于reflection机制的项目:
       Webwork : 一个MVC framework, www.opensymphony.com/webwork
       Hibernate: 一个高质量的O-R Mapping framework,hibernate.sourceforge.net
     一篇Dynamic Proxy的介绍文章:http://www.smotricz.com/kabutz/Issue005.html

   )



☆─────────────────────────────────────☆  
  NullPointer (空指针·莫之夭阏) 于  (Thu Nov 14 06:20:00 2002)  提到:

great!收获良多,
知道除了AspectJ之外,还有dreambean.com这个好地方,呵呵,我喜欢后者的技术路线。



【 在 gty 的大作中提到: 】                                                      
: 呵呵,xdoclet想要解决的问题,正是aop想要解决的问题,也是OO系统最大的          
: 缺陷。这个缺陷是什么?我也经常遇到,也常常在想,但都不是很清楚。但我          
: 可以把自己不成熟的想法要大概描述一下,希望大家指正:                          
: 1. 首先,软件的发展主题是代码复用。这一点恐怕没有疑问。从面向过程到           
: 面向对象,是为了复用;现在从面向对象,到面向aspect(怎么翻译,cloudor?),   

: 也是为了复用。所以AOP是OOP的一种自然进步,不是否定。                          
: 2. 面向过程是线性思维,面向对象是平面思维,面向aspect是立体思维(多维?),   

: 这和软件过程的发展有相同之处。起初的软件过程比较强调流程,需求-设计-编码      
: -测试;后来发觉不是所有的软件系统都是类似流程,例如中国的项目和国外的         
: 项目过程就大相径庭(没有好坏之分,都是解决问题的),因此大家就来归纳,就像    
: ...................

☆─────────────────────────────────────☆  
liyawei (首都机场的士司机杀手) 于  (Thu Nov 14 09:24:32 2002)  提到:

真好
我看了一下,发现AOP技术过分依赖JAVA语言本身的特性
如PROXY,REFLECTION。如何在不同语言下实施呢?


☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Thu Nov 14 12:03:39 2002)  提到:

至少c#在这方面好像比java还强
看gty大牛的文章真是长见识啊!呵呵


☆─────────────────────────────────────☆  
rehte (Ava) 于  (Thu Nov 14 15:24:27 2002)  提到:

看大牛的文章,巨长见识。
谢谢gty!



☆─────────────────────────────────────☆  
  cloudor (大功即将告成!!!) 于  (Thu Nov 14 16:19:18 2002)  提到:


嗯,感觉你前一部分说的是把编程的思想应用到开发工作的组织中来。

需求-设计-编码-测试,对应面向流程的思想;
RUP,对应面向对象的思想;
XP,对应面向aspect的思想。



☆─────────────────────────────────────☆  
  kaoyan (xixi) 于  (Thu Nov 14 18:58:31 2002)  提到:

怎么象c#里面的attribute



☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Fri Nov 15 02:30:48 2002)  提到:

AOP本身只是概念,和语言确实没有关系,事实上,几乎大部分
高级语言目前都有AOP的实现(http://aosd.net/tools.html)

proxy和reflection只是rickard的Java AOP实现中的主要技术,
很多语言都有代码“内省(introspect)”机制,例如C#和COM.
但dynamic proxy就不知道是不是都有了。



☆─────────────────────────────────────☆  
  gty (宜良-丽江-蝴蝶泉) 于  (Fri Nov 15 02:33:30 2002)  提到:

是啊,我也很喜欢:)webwork,xdoclet都是非常简单实用的工具。

☆─────────────────────────────────────☆  
  gty (宜良-丽江-蝴蝶泉) 于  (Fri Nov 15 02:35:18 2002)  提到:

听说C#可以在运行时访问注释,是真的吗?(我没用过C#)



☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Fri Nov 15 03:01:30 2002)  提到:


:)只是把两者做一下类比,都是比较新,又很难理解的概念,所以
希望串起来能互相验证验证。

可惜最近太忙,只有晚上有时间上BBS,不能和大家多讨论AOP。我也
是最近刚接触这方面的东西,但一下子觉得非常有共鸣,解决了在J2EE
开发方面的很多疑惑。

今天我用dynamic proxy初步实现了目前用xdoclet自动生成的EJBProxy
(功能主要是method delegation,local and remote switch, simple failover),
感觉真是很简单,以后再也不用为每个session bean自动生成EJBProxy了。

如果大家有兴趣,可以一起来做个基于AOP的框架(J3EE?),至少目前我们可以
交流和共享一些Aspect和Interceptor。

太晚了,睡觉去了,拜拜。


☆─────────────────────────────────────☆  
neek2000 (泥壳) 于  (Fri Nov 15 08:44:27 2002)  提到:

景仰啊,学到不少东西……



☆─────────────────────────────────────☆  
liyawei (感谢NEEK2000友情提醒中) 于  (Fri Nov 15 09:20:48 2002)  提到:

的确,使用DYNAMIC PROXY对EJB这种模型来说
在客户端是非常干净的,而且可以方便的加入各种QOS,好象JBOSS里面用了不少
从AOP的角度来看,这种解决方案应该是最好。不过与其他基于静态STUB的方案比
DYNAMIC PROXY的开销实在太大,似乎差了一两个数量级。?
基于反省的东西就是慢。不知道GTY手上有没有一些数据


☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Fri Nov 15 12:52:48 2002)  提到:

主要就是kaoyan讲的attribute吧,提供元数据,这点真的很牛啊
对实现AOP肯定也有帮助吧
您认为AOP思想成熟了会不会导致新的语言产生呢?


☆─────────────────────────────────────☆  
  gty (宜良-丽江-蝴蝶泉) 于  (Sat Nov 16 20:19:47 2002)  提到:


呵呵,我可没资格说。
但作为一个程序员,我还是希望变化不要太大,因此
rickard的方法比aspectJ对我来说更有吸引力。




☆─────────────────────────────────────☆  
  gty (宜良-丽江-蝴蝶泉) 于  (Sun Nov 17 03:50:17 2002)  提到:

刚才我做了一个简单的测试,结论是dynamic proxy的确会
带来一定的系统开销,但是对实际系统的影响应该很小。

测试描述:
   interface: BusinessInterface
          定义method : String echoString(String str);
   impl:      CoreImpl implements BusinessInterface
          实现echoString(String str),本测试提供了两种实现
          a. 轻负载
              仅仅是 return str;
          b. 模拟实际负载
              在sleep 10ms之后,return str;
   static Proxy: MyProxy implements BusinessInterface
          属性 private CoreImpl coreImpl = new CoreImpl();
          实现echoString(String str)
             return "myproxy:"+ coreImpl.echoString(str);
   Dyna Proxy's handler :MyHandler implements InvocationHandler
          构造函数将CoreImpl对象传入
            final Object realObject;

            public MyHandler(Object realObject) {
                this.realObject = realObject;
            }
          实现java.lang.refelect.Proxy.InvocationHandler的invoke方法
            public Object invoke(
                Object target,
                java.lang.reflect.Method method,
                Object[] arguments)
                throws Throwable {
                return "myproxy:"+method.invoke(realObject, arguments);
            }

   Test Class: Tester
          1)测试静态Proxy
        public static void testMyProxy(int count)
        {
                long start = System.currentTimeMillis();

                MyProxy proxy = new MyProxy();

                long created = System.currentTimeMillis();

                System.out.println("create time:"+(created-start));

                for (int i = 0; i<count;i++)
                        proxy.echoString("ok");

                long end = System.currentTimeMillis();

                System.out.println("execution:"+(end-created));

                System.out.println("duration:"+(end-start));
        }
          2)测试动态Proxy
        public static void testDynaProxy(int count)
        {

                long start = System.currentTimeMillis();
                BusinessInterface proxy = (BusinessInterface)java.lang.reflect.P
roxy.newProxyInstance(
                                BusinessInterface.class.getClassLoader(),
                                new Class[] {BusinessInterface.class},
                                new MyHandler(new CoreImpl()));

                long created = System.currentTimeMillis();

                System.out.println("create time:"+(created-start));

                for (int i = 0; i<count;i++)
                        proxy.echoString("ok");

                long end = System.currentTimeMillis();

                System.out.println("execution:"+(end-created));

                System.out.println("duration:"+(end-start));
        }
    JDK1.4.0
    CPU: Intel P3 800
    OS: Windows 2000


测试结果 (所有时间单位都是ms)

对方法调用的测试结果
1) 当CoreImpl为轻负载实现(a)时,结果如下
count         100             1000           10000          100000
         static  dyna    static  dyna    static  dyna    static  dyna
execute   0      10       10     30       30     80      140    260
平均额外负载    .1              .02             .005            .0012

分析:方法执行时间的差距随着执行次数增加,逐渐减小

2) 当CoreImpl模拟实际负载(10ms)(b)时,结果如下
count        100              1000
          static  dyna     static  dyna
execute   1011   1012     10064   10095
平均额外负载      .11              .031

分析: 方法执行时间的差距很小
       平均额外负载和轻负载时大致相同

结论

Dynamic Proxy的构建和执行会带来一定的系统额外开销,当调用100次时,平均额外的
负载为.1毫秒。但是,以下因素会让这种开销的影响减小甚至消除:
* 将构建的Dynamic Proxy实例缓存
* 随着方法的执行次数增加,平均额外负载也会迅速减小
因此,对于大多数“应用程序”(数据库操作/远程调用)来说,使用Dynamic Proxy对
系统性能的影响应该很小,更不会有“一两个数量级”的差距。

实例:hibernate使用了dynamic proxy进行lazy loading,使用了大量reflection api
进行O-R mapping,但是其却是同类产品中速度最快的之一(当然也不是因为用了reflectio
n:))


☆─────────────────────────────────────☆  
cloudor (大功即将告成!!!) 于  (Sun Nov 17 09:16:40 2002)  提到:


嗯,该好好学学,少点空想,多点实际测试。



※ 修改:·qyjohn 于 Mar 30 09:43:32 修改本文·[FROM:   219.238.203.*]           

索引页面|上一篇|下一篇


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
125.000ms