刚刚在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. ASP.NET 网站在域环境内配置授权访问

    在 IIS 中,通常需要配置域中的某些用户或者用户组有权限访问部署的 WEB 站点或者 WEB 服务.我们知道要实现这种功能可以有如下几种方式: 代码,获取当前用户,到域服务器上去验证当前用户是否为合 ...

  2. QT 线程池 + TCP 小试(一)线程池的简单实现

    *免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378 很久以前做过ACE + MFC/QT 的中轻量级线程池应用,大概就 ...

  3. node.js 入门教程(beginnder guide

    非常好的教程: node入门: JavaScript与Node.js JavaScript与你 简短申明 服务器端JavaScript “Hello World” 一个完整的基于Node.js的web ...

  4. opennebula extend(expending) auth module ldap

    LDAP Authentication addon permits users to have the same credentials as in LDAP, so effectively cent ...

  5. [置顶] 与小伙伴共勉的java有关jvm的知识(一),小鸟尽量写得详细哦,欢迎讨论,谢绝喷子

    JAVA运行在JVM之上,JVM的运行状况会对程序产生很大的影响,因此了解一些JVM的东东,对于编写稳定的,高性能的java程序至关重要.这是JVM的规范中定义的标准结构图: 以上标准是JVM标准中定 ...

  6. Linux学习笔记1:配置Linux网络和克隆虚拟机并更改配置

    一.配置Linux网络 在安装Linux的时候,一定要保证你的物理网络的IP是手动设置的,要不然会在Linux设置IP连通网络的时候会报network is unreachable 并且怎么也找不到问 ...

  7. AndroidUI 视图动画-旋转动画效果 (RotateAnimation)

    RotateAnimation,能实现Android的视图的旋转效果,废话不多说直接上代码. 新建一个Android 项目,在activity_main.xml中添加一个按钮,然后使用Relative ...

  8. localStorage点击次数存储

    <!DOCTYPE html><html><head><meta charset="utf-8"> <title>菜鸟教 ...

  9. ios模拟器安装.app

    相对于xcode的run,然后再在安装到模拟器上测试,如果是个人开发的话,那还好. 要是是团队开发,那每次其他的童鞋就都需要update最新的文件下来再编译运行了. 而且,一些测试的童鞋也不会打开xc ...

  10. 【转】C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部

    PS:文末的附件已更新,这次我放到博客园里面了,不会弹出广告,放心下载,O(∩_∩)O谢谢! 这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开 ...