`
javaEE_dev
  • 浏览: 26394 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

:Without SSH/JSP/Servlet,不走寻常路,Java可以更酷

阅读更多
ZHH2009 写道
标题的构思来源于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公司的超轻量级Http服务器又过于简单了,连HTTP/1.1的大多数功能都没实现,
除了参考一下它的SSL实现外基本上毫无价值。

本想在现有的JSP/Servlet容器上做一下简单扩展就得了,
哪知也是四处碰壁(还下过Jetty的源代码下来看了一会,结果发现比Tomcat6还糟),
后来决定对Tomcat6与Sun的Http服务器进行大刀阔斧的改造,
完成了一个精简版的改良后的基于NIO的Http服务器(目前的版本只有60个左右的Java源文件),
并且能跟Javac编译器完美结合,能直接运行Java源文件。

在模型层这一块,最初是从书上和网络上对Hibernate进行应用层次的研究,
但是并不想深入源代码,因为代码量也实在是太多了,倒是对Ibatis2.0深入研究了一下,
Ibatis2.0代码量比较少,也简单,看了不到一星期就基本上看完了,不过现在并没留下深刻映象,
因为并没发现什么特别出彩的地方,Ibatis2.0还是离不开xml,而我想要完全抛弃xml。

当然,不管Hibernate也好,Ibatis2.0也好,相比Rails的ActiveRecord还是逊色了点,
不过我的目标并不是要造一个Hibernate、Ibatis2.0或ActiveRecord这样的轮子,
我的要求更高,我在想如何才能写更少的代码,如何才能实现自动化?
可不可以在服务器启动时或运行时动态解析数据库的元数据,
让编译器跟据这些元数据动态生成类呢?
接着我转去研究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中,
因为在Douyu服务器的启动脚本中并没有进行过多的环境检测,
而是直接使用了%JAVA_HOME%\bin目录下的java命令来启动Java HotSpot VM。


1.2 安装Douyu服务器

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   //服务器的启动脚本和运行时类库都在这里
conf  //服务器的配置文件放在这里
lib   //应用程序使用到的第三方类库(比如数据库驱动)都放在这里,初始情况下是个空目录
logs  //存放服务器运行期间的日志(目前日志只是输出到控制台),初始情况下是个空目录
temp  //服务器运行期间用到的临时文件夹(比如上传文件时可能会用到),初始情况下是个空目录
work  //服务器运行期间的工作目录,初始情况下是个空目录

了解了这些就足够了,目前你不需要做任何配置。







2. 体验Douyu



2.1 如何运行Douyu服务器?


点"开始->运行",输入cmd,打开一个控制台,切换到D:\Douyu\bin目录,
然后输入 douyu  启动Douyu服务器 (要关闭Douyu服务器连按两次Ctrl+C既可)
见下图:



如果你是第一次打开操作系统第一次启动JVM运行Java程序
或是隔了一个小时左右重新启动JVM运行Java程序,这时可能要等待几秒钟(5--10秒),
出现这种情况并不是Douyu服务器的问题,而是JVM本身或操作系统的问题,
通常启动Douyu服务器如果不加载数据库的话,一般在一秒钟内就能启动完成了。

Douyu服务器默认情况下监听的主机名是: localhost,端口: 8000

如果你不喜欢这样的默认配置,
或者最常见的情况是端口8000被占用了
(一般抛出异常: java.net.BindException: Address already in use)
你可以打开conf\server.java这个服务器配置文件,
配置文件本身就是一个java源文件,参数的配置使用Java语言的Annotation语法,
所有与服务器配置有关的都是Annotation或是Enum,全都在com.douyu.config包中定义。
import com.douyu.config.*;

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



要修改默认主机名和端口,请修改hostName和port的值,
hostName是一个字符串,可以用IP地址来表示,port是一个整型(int)值。


其他很多参数先不罗列了,使用到时再详细说明。


当你修改了conf\server.java后,你也不需要自己去手工编译它,
启动Douyu服务器时,Douyu会自行决定是否要编译它。
如果conf\server.java存在语法错误,那么编译失败,
Douyu服务器的启动也会失败,同时向你显示编译错误信息。



下文中假定Douyu服务器已启动,监听的主机名是: localhost,端口是: 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!");
	}
}


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

不过这里并不打算介绍HTTP协议,如果你有兴趣,可以把RFC2616下下来研究。

Douyu服务器收到浏览器发来的请求消息后,
特别留意 "GET /HelloWorld HTTP/1.1" 这一行消息,
其中的"/HelloWorld"表示想要获取Douyu服务器上的哪些资源,
资源有静态的(如html、jpg等文件),也有动态的,在Douyu服务器中动态资源只有一种,
凡是带有@Controller这个Annotation的Java源文件都是可以直接通过uri访问的动态资源。

不过Douyu服务器不能根据uri的表面特征一眼就看出它是动态的还是静态资源,
服务器内部有一个专用的资源装载器,装载器的搜索根目录是从apps这个地方开始的,
资源装载器会尝试将apps目录与uri组合成一个java.io.File对象,
如果File对象存在,那么它就是一个静态资源,
然后由Douyu服务器内部的静态资源处理器给浏览器发送包含有文件内容的响应消息;

如果File对象不存在,资源装载器把请求的uri当成一个类名,
然后尝试采用类装载器的方式装载类,如果找不到那么就直接返回未找到(404)消息;
如果找到了,并且uri是第一次请求的,资源装载器会返回java源文件,
然后把java源文件交给Douyu服务器内置的编译器处理,编译器的处理过程很复杂,
这里就不深入说明了,总之它会为你动态生成HelloWorld的实例,
然后调用它的index这个缺省的public方法,
之后调用out.println()方法把"Hello World!"发送给浏览器。

分享到:
评论

相关推荐

    ethminer-0.16.0.dev3

    - stratum mining without proxy - OpenCL devices picking - farm failover (getwork + stratum) ## Table of Contents - [Install](#install) - [Usage](#usage) - [Examples connecting some pools](#...

    最新Color Admin1.9 - bootstrap3响应后台模板+前端网页模板

    Page Without Sidebar Page With Right Sidebar Page With Minified Sidebar Page With Two Sidebar Page Full Height Page With Simple Line Icons Page With Ionicons Page With Light Sidebar Page With...

    java反编工具java反编工具

    DJ Java Decompiler ver. 2.9.9.60 for Windows 95/98/Me/NT/2000 THE PURPOSE: DJ Java Decompiler is decompiler for Java which reconstructs the original source code from the compiled binary CLASS files ...

    OpenSSH 9.3 CentOS7 RPM安装包

    基于centos7编译的openssh9.3的安装包,使用x11-ssh-askpass让openssh不在依赖openssl1.1.1。 更新前:注意备份好/etc/ssh和/etc/pam.d/ ,一般建议开启telnet增加一条备用登陆通道 更新操作:rpm -Uvh openssh-*....

    http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd

    accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders...

    spring 最新框架jar

    can focus on application-level business logic, without unnecessary ties to specific deployment environments. The framework also serves as the foundation for [Spring Integration][], [Spring Batch][] ...

    ffprobe-20190623-bc3306f-win64-static可执行文件

    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General ...

    jquery翻书效果

    covers: false, // used with "closed", makes first and last pages into covers, without page numbers (if enabled) pagePadding: 10, // padding for each page wrapper pageNumbers: true, // display page ...

    ffplay-20190623-bc3306f-win64-static 可执行文件

    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General ...

    SSH移植到android系统步骤.doc

    SSH移植到Android系统步骤 SSH(Secure Shell)是一种安全的远程登录协议,常用于Linux系统中。但是,Android系统并不具备SSH功能,这篇文章将讲述如何将OpenSSH移植到Android系统中。 Step 1: 获取OpenSSH源码 ...

    Thumbor的Java客户端Pollexor.zip

    Pollexor 是 Thumbor 图片服务的 JAVA 客户端,兼容 Android 平台。Maven:  <groupId>com.squareup</groupId>  <artifactId>pollexor  <version>2.0.2</version> </dependency>Gradle:compile '...

    TRichView_v14_5

    Full source code (without help and demo projects) See Install.chm for the instructions. See "New in version 14" and "New after version 14" in the help file ------------------------------ Additional ...

    Android源码编译make的错误处理

    - `/bin/bash: bison:找不到命令`,可以通过安装`bison`来解决。 - 检查构建工具版本时的提示,可以通过更新或重新安装对应的工具来解决。 #### 四、总结 通过以上步骤,可以在32位Linux系统上顺利编译Android ...

    《Java Servlet编程(第二版)》英文版 chm (含源码)

    The Java 2, Enterprise Edition (J2EE), specification has included servlets as a core component, and application server vendors wouldn't be caught dead without a scalable servlet implementation....

    编译好的OpenCV4.0.1+Qt5.9+Contrib版

    without hdf module without BUILD_opencv_world Release: many dll/dll.a General configuration for OpenCV 4.0.1 ===================================== Version control: unknown Extra modules: Location...

    HP_Socket5.5.3.ec

    HPSocket For E 5.5.3 ...* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

    编译好的OpenCV3.4.2+Qt5.9+Contrib版

    without hdf module without BUILD_opencv_world Release: many dll/dll.a General configuration for OpenCV 3.4.2 ===================================== Version control: unknown Extra modules: Location...

    yolo算法 3000多千张多类别口罩检测数据集

    3000多千张多类别口罩检测数据集,数据集目录已经配置好,yolo格式(txt)的标签,划分好 train,val, test,并附有data.yaml文件,yolov5、yolov7、yolov8等算法可以直接进行训练模型, 数据集和检测结果参考: ...

    mysql-connector-java-8.0.11.jar

    Fri Jun 08 13:09:27 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection ...

    yolov5多类别口罩检测训练权重+3000多千张多类别口罩检测数据集+pyqt界面

    yolov5多类别口罩检测训练权重, 3000多千张多类别口罩检测数据集,数据集目录已经配置好,yolo格式(txt)的标签,划分好 train,val, test,并附有data.yaml文件,yolov5、yolov7、yolov8等算法可以直接进行训练模型...

Global site tag (gtag.js) - Google Analytics