刚刚在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差点儿相同):

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

  1. import
     com.douyu.config.*;
  2. @Server
    (
  3. port=8000
    ,
  4. .................
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 程序代码

  1. //相应apps/HelloWorld.java文件
  2. import
     java.io.PrintWriter;
  3. import
     com.douyu.main.Controller;
  4. @Controller
  5. public
     class
     HelloWorld {
  6. public
     void
     index(PrintWriter out) {
  7. out.println("Hello World!"
    );
  8. }
  9. }
//相应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请求消息,消息内容相似这样:

  1. GET /HelloWorld HTTP/1.1
  2. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,......
  3. Accept-Language: zh-cn
  4. Accept-Encoding: gzip, deflate
  5. User-Agent: Mozilla/4.0
     (compatible; MSIE 6.0
    ; Windows NT 5.1
    ; SV1; Maxthon)
  6. Host: localhost:8000
  7. 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”的国人项目的更多相关文章

  1. 在有道词典程序文件夹发现一个后缀名为sql的数据库(SQLite)

    缘起 在清理电脑磁盘的时候,看一看各安装文件夹有占用了多大容量,发现有道词典居然达140MB了,于是进去看看. 发现个有趣的文件:XXX.sql. 首先我们看一看它的安装文件夹的结构: Dict └─ ...

  2. 从偶然的机会发现一个mysql特性到wooyun waf绕过题

    从偶然的机会发现一个mysql特性到wooyun waf绕过题 MayIKissYou | 2015-06-19 12:00 最近在测试的时候,偶然的机会发现了一个mysql的特性, 为啥是偶然的机会 ...

  3. linux 下程序员专用搜索源码用来替代grep的软件ack(后来发现一个更快的: ag), 且有vim插件的

    发现一个比ack更快更好用的:  https://github.com/ggreer/the_silver_searcher   , 使用时命令为ag,它是基于ack的代码二次开发的,所有使用方法基本 ...

  4. 又发现一个visual studio 2015的坑啊。

    又发现一个visual studio 2015的坑啊...我的后台管理的目录名称叫@duck, 但是在新版VS2015中打开项目后编译,出现错误: Error opening response fil ...

  5. RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接

    如果你的服务器有如下错误: “RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接.” 可能的有2种: 1:你试试能否能继续远程登陆,有可能你的远程登陆组件出现问题. 2:有人攻击 ...

  6. 打造一个高逼格的android开源项目——小白全攻略 (转)

    转自:打造一个高逼格的android开源项目 小引子 在平时的开发过程中,我们经常会查阅很多的资料,最常参考的是 github 的开源项目.通常在项目的主页面能看到项目的简介和基本使用,并且时不时能看 ...

  7. 一个tomcat同时部署多个项目

    一个tomcat同时部署多个项目 1. 注意事项: 1. 每一个service的端口号不能产生冲突 2. service的name属性的值可以重复 name="Catalina" ...

  8. 使用go语言开发一个后端gin框架的web项目

    用liteide来开发go的后端项目,需要注意的是环境变量要配置正确了 主要是GOROOT, GOPATH, GOBIN, PATH这几个, GOPATH主要用来存放要安的包,主要使用go get 来 ...

  9. WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping 异常详细信息: System.InvalidOperationException: WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的

    WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping.请添加一个名为 jquery (区分大小写)的 ScriptRes ...

随机推荐

  1. Delphi 实现无窗口移动(发WM_NCHITTEST消息计算,然后再发WM_SYSCOMMAND消息,带参数SC_DRAGMOVE)

    procedure imgListMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ...

  2. 很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序

    很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用m ...

  3. MYSQL中limit的使用

    limit是mysql的语法select * from table limit m,n其中m是指记录开始的索引,从0开始,表示第一条记录n是指从第m+1条开始,取n条.select * from ta ...

  4. LOL是什么意思? - 已解决 - 搜狗问问

    LOL是什么意思? - 已解决 - 搜狗问问 N A T S U . |分类:QQ工具栏 2009-05-04 LOL是什么意思? 满意答案 Shim Nyong 19级 2009-05-04 LOL ...

  5. Android UI SurfaceView的使用-绘制单个图型或多个图形

    新建MyView类继承自SurfaceView: public class MyView extends SurfaceView implements SurfaceHolder.Callback { ...

  6. Magento - get Attribute Options of the dropdown type attribute

      $attribute_code = "color"; $attribute_details = Mage::getSingleton("eav/config" ...

  7. 软交所--微软将对IE浏览器进行关键性安全更新

    微软于当地时间周四宣布下周二,即本月的"补丁星期二"推送九个安全升级. 当中最重要的就是解决IE浏览器远程运行代码(RCE)漏洞,这个漏洞影响从IE6至IE11全版本号,全部Win ...

  8. sctf pwn200

    题目给出了pwn200和libc.so.使用IDA查看程序,发现逻辑很简单. 使用checksec查看pwn200的安全属性,如下图: 发现NX enabled,No PIE. 在第一次读(0x080 ...

  9. OCP prepare 20140701

    1. rman的完全备份,和不完全备份 Oracle 数据库可以实现数据库不完全恢复与完全恢复.完全恢复是将数据库恢复到最新时刻,也就是无损恢复,保证数据库无丢失的恢复.而不完全恢复则是根据需要特意将 ...

  10. mysql自定义循环函数

    FUNCTION deyes.f_getSplitStringByIndex1_8(stringIn text, delimiter varchar(10), indexIn int) RETURNS ...