发现一个名为“Douyu”的国人项目

2023-07-10,,

刚刚在javaeye看到一个名为Douyu的国人项目,认为搞下去未来可能非常有意思,放到blog上做个标记。

——————下面是转载的作者原文———————

原文地址例如以下:http://zhh2009.javaeye.com/blog/517796

标题的构思来源于Rod Johnson的那本"Without EJB"以及CCTV5中一句耳熟能详的广告词,

只是此文并非用来批判SSH(Struts、Spring、Hibernate)/JSP/Servlet的,

也不是为某品牌做广告,而是用来分享这将近一年来的研究心得。

去年圣诞节时曾在JavaEye发过一两篇文章,只是如今找不到了,

文章内容提到要在3个月左右的时间内设计出一个有别于SSH的新型MVC框架,

设计的起点最初是以JSP/Servlet为基础的,尽管在两个多月后有了个雏形,

可是跟Rails这种框架相比还是没有明显的优势,

比方在不使用反射的情况下,

非常难将不同的uri相应到Servlet类中的public方法。

(Servlet类指的是继承自javax.servlet.http.HttpServlet的类)

每次改动Servlet类的源码时总得经过烦人的手工编译步骤(有时还不得不重新启动Tomcat),

还有与数据库打交道的模型层也得人工干预,一堆烦人的映射配置。

那三个月内时常有沮丧感,似乎已走近了死胡同!

后来心一狠,决心甩开JSP/Servlet那一堆条条框框,把设计的起点再往下深一个层次。

由于2007年曾具体研究过Java语言的编译器(javac)实现细节,所以从编译器着手,

可是编译器的强项在于分析Java源码,无法处理Http请求,

接着在网上把Tomcat6的源码下下来研究了三个月,

期间顺便研究了Sun公司的超轻量级Http服务器"com.sun.net.httpserver"的源码,

同一时候具体学习HTTP/1.0(RFC1945)与HTTP/1.1(RFC2616)协议。

可是Tomcat6过于臃肿了,包括的Java文件超过了1300个,

光是解析server.xml与web.xml的代码看完后就让人有烦躁感。

(如org/apache/tomcat/util/digester与org/apache/catalina/startup包中的非常多类)

另外最重要一点,Tomcat6採用的是Eclipse JDT编译器,不过用来编译JSP文件,

编译器在控制层没有发挥一点作用。

而Sun公司的超轻量级Httpserver又过于简单了,连HTTP/1.1的大多数功能都没实现,

除了參考一下它的SSL实现外基本上毫无价值。

本想在现有的JSP/Servlet容器上做一下简单扩展就得了,

哪知也是四处碰壁(还下过Jetty的源码下来看了一会,结果发现比Tomcat6还糟),

后来决定对Tomcat6与Sun的Httpserver进行大刀阔斧的改造,

完毕了一个精简版的改良后的基于NIO的Httpserver(眼下的版本号仅仅有60个左右的Java源文件),

而且能跟Javac编译器完美结合,能直接执行Java源文件。

在模型层这一块,最初是从书上和网络上对Hibernate进行应用层次的研究,

可是并不想深入源码,由于代码量也实在是太多了,倒是对Ibatis2.0深入研究了一下,

Ibatis2.0代码量比較少,也简单,看了不到一星期就基本上看完了,只是如今并没留下深刻映象,

由于并没发现什么特别出彩的地方,Ibatis2.0还是离不开xml,而我想要全然抛弃xml。

当然,无论Hibernate也好,Ibatis2.0也好,相比Rails的ActiveRecord还是逊色了点,

只是我的目标并非要造一个Hibernate、Ibatis2.0或ActiveRecord这种轮子,

我的要求更高,我在想怎样才干写更少的代码,怎样才干实现自己主动化?

可不能够在server启动时或执行时动态解析数据库的元数据,

让编译器跟据这些元数据动态生成类呢?

接着我转去研究JDBC-1.2/JDBC-2.1/JDBC-3.0/JDBC-4.0规范,研究数据库驱动的开发手冊。

我得从零開始,我眼下的实现是这样做的:你能够在你自己的Java源文件里直接引用动态生成的类,

就像这些类是你自己写的一样,ORM已基本上实现自己主动化了,2.9 节专门讲Douyu的ORM。

最后一点值得一提的是,我在Java语言层次引入了权限管理模型,

只是你别操心,我并没有引入新的Java语言语法,

仅仅是借助Annotation扩充了某些特殊的语义。

眼下这个权限管理模型的粒度仅仅是划分为功能、字段权限两个等级,

并没有实现与详细业务相关的数据权限,只是在未来的路线图中有打算引入工作流模型,

到时会努力尝试各种实现数据权限的方案。

与权限相关的细节请看2.8节 Douyu的权限模型

折腾了半年后,发现已不再是个MVC框架了,我想称为平台更合适,

一种执行在JVM之上的新型平台,我给她起了个名字: Douyu

(呵呵,名字的由来临时保密,或许你能猜出来。。。)

尽管孤军奋战将近一年,自我感觉小有成就,可是还有非常多不怎么惬意的地方,

各位大牛们或许更牛,看见不爽砸砖头便是。

Ok,上干货。

1. 安装配置

(这里仅仅针对Windows平台,特别是XP操作系统,由于我没其它试验环境)

1.1 安装JDK

Douyu是在JDK1.6下开发的,不支持也不打算支持JDK1.4及更早的版本号,JDK1.5我没有測试过,

所以我仅仅能推荐你安装JDK1.6了
,安装细节我想你都会,

唯一要注意的一点是:最好是建个JAVA_HOME环境变量,然后把%JAVA_HOME%/bin增加到Path中,

由于在Douyuserver的启动脚本中并没有进行过多的环境检測,

而是直接使用了%JAVA_HOME%/bin文件夹下的java命令来启动Java HotSpot VM。

1.2 安装Douyuserver

Douyu项目主页眼下放在:

http://code.google.com/p/douyu/

请先下载二进制版的压缩文件:

http://douyu.googlecode.com/files/Douyu_0_1_0.rar

眼下的版本号是:0.1.0,版本号号非常小,但大多数功能都包括了,

我并不推荐你用于工业级别的产品开发,

由于还不稳定,眼下仅仅适合分享、交流、尝鲜目的。

下下来后直接解压到一个你选定的文件夹(假定你解压到了D:/Douyu文件夹)

D:/Douyu文件夹里头有以下7个文件夹(跟Tomcat6差点儿相同):

    apps  //应用程序的源码放在这里,里头有一些java源文件是以下的演示中用到的,当然你能够全都删了。
    bin   //server的启动脚本和执行时类库都在这里
    conf  //server的配置文件放在这里
    lib   //应用程序使用到的第三方类库(比方数据库驱动)都放在这里,初始情况下是个空文件夹
    logs  //存放server执行期间的日志(眼下日志仅仅是输出到控制台),初始情况下是个空文件夹
    temp  //server执行期间用到的暂时文件夹(比方上传文件时可能会用到),初始情况下是个空文件夹
    work  //server执行期间的工作文件夹,初始情况下是个空文件夹
apps  //应用程序的源码放在这里,里头有一些java源文件是以下的演示中用到的,当然你能够全都删了。
bin //server的启动脚本和执行时类库都在这里
conf //server的配置文件放在这里
lib //应用程序使用到的第三方类库(比方数据库驱动)都放在这里,初始情况下是个空文件夹
logs //存放server执行期间的日志(眼下日志仅仅是输出到控制台),初始情况下是个空文件夹
temp //server执行期间用到的暂时文件夹(比方上传文件时可能会用到),初始情况下是个空文件夹
work //server执行期间的工作文件夹,初始情况下是个空文件夹

了解了这些就足够了,眼下你不须要做不论什么配置。

2. 体验Douyu

2.1 怎样执行Douyuserver?

点"開始->执行",输入cmd,打开一个控制台,切换到D:/Douyu/bin文件夹,

然后输入 douyu  启动Douyuserver (要关闭Douyuserver连按两次Ctrl+C既可)

见下图:

假设你是第一次打开操作系统第一次启动JVM执行Java程序

或是隔了一个小时左右又一次启动JVM执行Java程序,这时可能要等待几秒钟(5--10秒),

出现这样的情况并非Douyuserver的问题,而是JVM本身或操作系统的问题,

通常启动Douyuserver假设不载入数据库的话,一般在一秒钟内就能启动完毕了。

Douyuserver默认情况下监听的主机名是: localhost,port: 8000

假设你不喜欢这种默认配置,

或者最常见的情况是port8000被占用了

(一般抛出异常: java.net.BindException: Address already in use)

你能够打开conf/server.java这个服务器配置文件,

配置文件本身就是一个java源文件,參数的配置使用Java语言的Annotation语法,

全部与server配置有关的都是Annotation或是Enum,全都在com.douyu.config包中定义。

    import
     com.douyu.config.*;
    @Server
    (
    port=8000
    ,
    .................
import com.douyu.config.*;

@Server(
port=8000,
.................

要改动默认主机名和端口,请改动hostName和port的值,

hostName是一个字符串,能够用IP地址来表示,port是一个整型(int)值。

其它非常多參数先不罗列了,使用到时再具体说明。

当你改动了conf/server.java后,你也不须要自己去手工编译它,

启动Douyuserver时,Douyu会自行决定是否要编译它。

假设conf/server.java存在语法错误,那么编译失败,

Douyuserver的启动也会失败,同一时候向你显示编译错误信息。

下文中假定Douyuserver已启动,监听的主机名是: localhost,port是: 8000

下面全部样例都经过严格測试了,

我的JRE版本号:

D:/Douyu/bin>java -version

java version "1.6.0_16"

Java(TM) SE Runtime Environment (build 1.6.0_16-b01)

Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode, sharing)

測试浏览器用了两个:

傲游浏览器(IE6.0),

谷歌浏览器(Chrome 3.0.195.27)

2.2 Hello World!

2.2.1 程序代码

    //相应apps/HelloWorld.java文件
    import
     java.io.PrintWriter;
    import
     com.douyu.main.Controller;
    @Controller
    public
     class
     HelloWorld {
    public
     void
     index(PrintWriter out) {
    out.println("Hello World!"
    );
    }
    }
//相应apps/HelloWorld.java文件

import java.io.PrintWriter;
import com.douyu.main.Controller; @Controller
public class HelloWorld {
public void index(PrintWriter out) {
out.println("Hello World!");
}
}

2.2.2 手工编译已经Out了,你再也不须要这一步了。

2.2.3 执行HelloWorld

打开你心爱的浏览器,输入 http://localhost:8000/HelloWorld

假设你能看到下图中所看到的内容,恭喜你,你己经进入了Douyu的精彩世界。

(注:这是你第一次直接执行Java源文件,可能会等几秒钟(2--4秒),由于Douyu得初始化编译器)

2.2.4 程序代码说明

com.douyu.main包中的类大多数是Annotation,还包括一些重要的接口和类,

相当于java.lang,是你用Douyu开发程序时最经常使用到的,也是通往其它模块的高速入口,

本想让com.douyu.main包中的类像java.lang一样让编译器自己主动导入的,

可是考虑到非常多开发者更偏爱使用IDE,不同IDE内置的编译器不一样,

从而会引起找不到com.douyu.main包中的类的问题,所以最后决定放弃这种设计了。

@Controller 这个Annotation是用来告诉Douyu这是一个控制器,

当你在浏览器的地址栏中输入http://localhost:8000/HelloWorld 这种uri时,

浏览器内部一般会生成一个HTTP GET请求消息,消息内容相似这样:

    GET /HelloWorld HTTP/1.1
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,......
    Accept-Language: zh-cn
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0
     (compatible; MSIE 6.0
    ; Windows NT 5.1
    ; SV1; Maxthon)
    Host: localhost:8000
    Connection: Keep-Alive
GET /HelloWorld HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,......
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon)
Host: localhost:8000
Connection: Keep-Alive

只是这里并不打算介绍HTTP协议,假设你有兴趣,能够把RFC2616下下来研究。

Douyuserver收到浏览器发来的请求消息后,

特别留意 "GET /HelloWorld HTTP/1.1" 这一行消息,

当中的"/HelloWorld"表示想要获取Douyuserver上的哪些资源,

资源有静态的(如html、jpg等文件),也有动态的,在Douyuserver中动态资源仅仅有一种,

凡是带有@Controller这个Annotation的Java源文件都是能够直接通过uri訪问的动态资源。

只是Douyuserver不能依据uri的表面特征一眼就看出它是动态的还是静态资源,

server内部有一个专用的资源装载器,装载器的搜索根文件夹是从apps这个地方開始的,

资源装载器会尝试将apps文件夹与uri组合成一个java.io.File对象,

假设File对象存在,那么它就是一个静态资源,

然后由Douyuserver内部的静态资源处理器给浏览器发送包括有文件内容的响应消息;

假设File对象不存在,资源装载器把请求的uri当成一个类名,

然后尝试採用类装载器的方式装载类,假设找不到那么就直接返回未找到(404)消息;

假设找到了,而且uri是第一次请求的,资源装载器会返回java源文件,

然后把java源文件交给Douyuserver内置的编译器处理,编译器的处理过程非常复杂,

这里就不深入说明了,总之它会为你动态生成HelloWorld的实例,

然后调用它的index这个缺省的public方法,

之后调用out.println()方法把"Hello World!"发送给浏览器。

——————转载结束———————

在我们这个总喜欢以“不要反复发明轮子”为口头禅的国度里,其实不管是“反复发明的”抑或“自己独创的”现代事物全都屈指可数,出现Douyu这样一个“另类”的项目,不管怎么说都是非常有纪念意义的,起码来讲,它敢于牺牲ide支持,重构部分javac代码,以换取实时编译的举动,偶就肯定做不出来……另外在它是“平台”而非“框架”的问题上,偶坚定的支持原作者,由于标准的javaserver会和它有兼容性问题,它仅仅能自己充当平台……
就我看来,

Douyu要想做大做强,最简单的一条路就是作者自己开公司做应用,以应用推平台。否则,未来其研究意义或者远大于有用意义,毕竟使用Douyu不光是使用一个框架,也意味着放弃一系列Java现有体系,而使用它的一整套“平台“。

Douyu已实现的代码量并不大,加之暂不开源,所以我们无法做太多的评判。

但有些人用Douyu与play!framework对照,就我看来,如今还太早了些。最起码来说,

play!framework使用REST隐藏了HTTP,而Douyu现今仅仅是通过HTTP协议明码进行get与post传递,Play支持模板,而

Douyu临时仅仅能用静态的html作为页面,尽管两者都不用

又一次编译就能够部署文件,

但play!framework使用自己定义ClassLoader动态载入class,用Javassist改动字节码,使用自己修正的Compiler方式编译java源代码与模板,而

Douyu主要通过重写javac的java源代码部分实现动态编译,Play加上支持库等体积有40多MB,而

Douyu算上更改的javac部分也只是1MB多个一个jar

。从其实讲,Douyu更像一个play的原型系统,或者说一个未完好的play!framework,假设不照着play!framework的老路走下去,那么Douyu未来会变成什么样子如今还未可知,演化成一个我们无法想象的平台也大有可能。

此项目名为Douyu,就作者自己所言,似乎取自“斗鱼”的意思,而不是有些人所说的“多余”或者我第一印象的“都晕”,只是嘛,斗鱼这个名字事实上并不太好,由于不管日漫的《斗鱼》抑或台剧的《斗鱼》,主角都没能逃脱“骗子,流氓,赌徒”的阴影(尽管人都非常帅)……该项目未来的走势怎样,还是让我们拭目以待吧……

发现一个名为“Douyu”的国人项目的相关教程结束。

《发现一个名为“Douyu”的国人项目.doc》

下载本文的Word格式文档,以方便收藏与打印。