发现一个名为“Douyu”的国人项目
刚刚在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”的国人项目的更多相关文章
- 在有道词典程序文件夹发现一个后缀名为sql的数据库(SQLite)
缘起 在清理电脑磁盘的时候,看一看各安装文件夹有占用了多大容量,发现有道词典居然达140MB了,于是进去看看. 发现个有趣的文件:XXX.sql. 首先我们看一看它的安装文件夹的结构: Dict └─ ...
- 从偶然的机会发现一个mysql特性到wooyun waf绕过题
从偶然的机会发现一个mysql特性到wooyun waf绕过题 MayIKissYou | 2015-06-19 12:00 最近在测试的时候,偶然的机会发现了一个mysql的特性, 为啥是偶然的机会 ...
- linux 下程序员专用搜索源码用来替代grep的软件ack(后来发现一个更快的: ag), 且有vim插件的
发现一个比ack更快更好用的: https://github.com/ggreer/the_silver_searcher , 使用时命令为ag,它是基于ack的代码二次开发的,所有使用方法基本 ...
- 又发现一个visual studio 2015的坑啊。
又发现一个visual studio 2015的坑啊...我的后台管理的目录名称叫@duck, 但是在新版VS2015中打开项目后编译,出现错误: Error opening response fil ...
- RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接
如果你的服务器有如下错误: “RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接.” 可能的有2种: 1:你试试能否能继续远程登陆,有可能你的远程登陆组件出现问题. 2:有人攻击 ...
- 打造一个高逼格的android开源项目——小白全攻略 (转)
转自:打造一个高逼格的android开源项目 小引子 在平时的开发过程中,我们经常会查阅很多的资料,最常参考的是 github 的开源项目.通常在项目的主页面能看到项目的简介和基本使用,并且时不时能看 ...
- 一个tomcat同时部署多个项目
一个tomcat同时部署多个项目 1. 注意事项: 1. 每一个service的端口号不能产生冲突 2. service的name属性的值可以重复 name="Catalina" ...
- 使用go语言开发一个后端gin框架的web项目
用liteide来开发go的后端项目,需要注意的是环境变量要配置正确了 主要是GOROOT, GOPATH, GOBIN, PATH这几个, GOPATH主要用来存放要安的包,主要使用go get 来 ...
- WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping 异常详细信息: System.InvalidOperationException: WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的
WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping.请添加一个名为 jquery (区分大小写)的 ScriptRes ...
随机推荐
- 500多条Linux信息
http://www.cnblogs.com/zgqjymx/myposts.html?page=77 http://www.cnblogs.com/zgqjymx/tag/%E5%8E%9F%E5% ...
- rdlc部署zt
原文:rdlc部署zt 偶然间遇到“ 未能加载文件或程序集microsoft.reportviewer.winforms ……”的一个错误,以前web是遇到过,没想到winform部署也会遇到.找了半 ...
- nodejs学习笔记-1
nodejs入门-安装 nodejs是什么,刚接触了一段时间,我自己也说不清楚它.按我个人的简单理解,nodejs就是一个javascript的解析器,它让javascript不在局限于浏览器客户端. ...
- java的深复制与浅复制
今天座右铭-----浪费时间就等于慢性自杀 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原 来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复 ...
- 网易云课堂_程序设计入门-C语言_第五周:函数_2完数
2 完数(5分) 题目内容: 一个正整数的因子是所有可以整除它的正整数.而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数.例如6=1+2+3(6的因子是1,2,3). 现在,你要写一个程序, ...
- django中怎样生成非HTML格式的内容。
某些时候可能有这种需求.在网页中点击一个链接或者一个button希望返回一张图片.一个pdf文档.一个csv文档等而非HTML. 在diango中非常easy做到这些.django中的view用来接收 ...
- [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so
0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...
- VS2010中xercesc配置及简单示例
从官网下载xerces-c-3.1.1并解压,打开工程项目 xerces-c-3.1.1\projects\Win32\VC10\xerces-all\xerces-all.sln, 选择Xerces ...
- jQuery源码笔记——二
jQuery选择这样返回对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, con ...
- 望大神批评教育国庆无聊之作:ObjectValidator
起因: 本人国庆无聊,不知道干嘛, 所以模仿FluentValidation写了个简化版的ObjectValidator 个人设想是能用类似fluent的方式创建验证规则,然后使用者缓存并验证自己的对 ...