`
jusescn
  • 浏览: 122111 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一种一站式的Java Web框架的设计和实现

阅读更多

http://zwchen.iteye.com/blog/47085

一个月前,我发表了一篇文章《一种快速开发的Java Web架构设计和实现》(http://zwchen.iteye.com/blog/38278),匆匆发表,很欠成熟。经过一段时间的考虑,特别是吸取了Lucas Lee ,together ,lane_cn 等朋友的建议,重写了一份design文档,并且加一份tutorial文档,重构了所有代码,现在发表出来,听听大伙的意见。
本来很想把上次那三篇文章删掉,但也许会删掉到别人的宝贵评论,所以最后还是觉得保留,但我还是不太希望别人在那上面浪费时间,因为这篇文章就够了。
由于文章很长,而且javaeye论坛对word文档的paste支持不是很理想,我就只贴出文章的很小一部分,其它的全部,都在附件里,对此主题感兴趣的朋友,可以下载下来评价评价。
我在论坛潜水时,也不希望自己读到某些浪费时间的帖子(javaeye是我见过的文章质量最高的论坛),所以,我也不希望自己的帖子浪费大家宝贵的时间。想必上个帖子很浪费大家时间,深表歉意!
本文是我阶段性的总结,我想肯定受限于我的理论知识和项目经验,希望大家能够理解。
上个帖子最大的问题是:
[list=]1、对Map简单化了,抽象为一个plain结构,现在是对象图、树状结构。
2、原来所有持久化是spring jdbc,现在基本的CRUD是hibernate的dynamic-map方式。[/list]

现在,使用此框架的开发思路,可以将一个一定复杂度的CRUD操作减少到100行代码左右。

大家下载附件读吧,文章太长,我只贴出了很小一部分(附件文件夹下的docs目录里)。



MiniFramework有哪些核心思想,或是原理?
1、 元数据编程
这是MiniFramework中减少代码量和快速开发的一个很重要方面。
MiniFramework中有两类元数据,都非常简单:
Map和数据库映射 同时我们会避开Hibernate那种复杂的关联映射。而且这种映射可以自动生成。
JSP页面表单元素类型映射 因为http GET和POST提交数据都是文本key-value键值对,它们和数据库字段类型不匹配,我们必须还原其本来类型,但这个过程是自动化的。我打算开发eclipse插件,让这个映射代码也自动生成。
所有容易变更的信息,譬如sql,页面导航,对象实例引用…

2、 领域对象的表示:Map和List
MiniFramework里面没有具体的对象,譬如Account,Department,Book,而是以另外一种形式体现:Map,这是它最核心的思想。它可以实现所有具体对象的功能,包括对象图。并且易扩展、灵活。
为什么Map这么关键呢?因为它是领域模型的载体,也是自动持久化的目标对象。了解JSON、YAML和REST对MiniFramework中的map载体理解很有帮助:
REST:区别于Web Services SOAP协议的另外一种轻量级格式,更是一种Idea。REST和ajax协作开发,简直是绝配。REST是未来Web Services的发展趋势,更倾向于SOA,因为REST是以Resource为导向,而SOAP是以Action为导向,并且简单、易用。
JSON:这是ajax流行起来后,一种轻量集的数据交换格式。参考http://www.json.org/json-zh.html
YAML:在Ruby on Rails和Python这类动态语言最常用的一种文本数据格式,类似于Java最常用的XML,但更适合人读。参考:http: //wiki.nirvanastudio.org/wiki/YAML/5%B7%D6%D6%D3%C8%CF%CA%B6YAML
从技术的角度考虑,所有的MIS系统,无非是CRUD增删改查,而CRUD的对象,一种载体形式,就可以是Map和List(Map的复数形式)。
关于数据流的处理,可以参考《面向模式的软件架构:卷一》中的“管道模式”,异曲同工。
当然,复杂的MIS就不只是数据流,更倾向于业务流,譬如ERP中的物料管理,SCM的进销存,OA中的工作流。但它们底层都需要数据流支持。

3、 Map和List对象的展现技术:JSTL
当然,我并没有提出什么新东西,我只是提出一种新用法。JSTL是map和list的最好展现方式。如user.department.name,通过具体对象,或是Map对象图,都可以实现。但后者很少人用,因为所有的教程上面都会演示对象模型,用map是忌讳,不OO嘛。 Really?
对象展现技术和对象载体是两个非常关键的部分,关于对象展现的idea,可以参考:
OGNL:这是xwork里面对象属性存取的核心, OGNL也是EL(Expression Language)的一种实现方式。
Associative model of data:不同于关系模型和对象模型的另一种idea。

4、 Map 对象持久化技术:Hibernate
几乎我们所见的大多数Hibernate用法,都是持久化POJO,也就是JavaBean,但是Hibernate也支持另外一种持久化技术:Map持久化(dynamic-map)。
需要特别注意的是:对于Hibernate Map持久化,我只使用它的最基本功能,这意味着开发人员几乎都不需要理解hibernate,我已经将对象的CRUD和基本的List操作都封装起来的,调用工具方法就ok了。
这样,数据的四个最重要的方面中的三个被轻易解决了:对象的载体,对象的呈现,对象的持久化。还有一个,就是对象的复杂查询。

5、 对象数据查询技术:Spring JDBC Framework
应该说,这个方面对象的概念是最弱的,因为查询的往往是结果集。Spring的JDBC framework为我们提供了很好的封装的,另外,我在它的基础上再封装一下,开发人员的学习成本就更低了,它返回的也是Map或List。

6、 业务对象BO的CRUD抽象
每个业务对象,譬如UserBO,我们要求它实现其CRUD操作,R(Read or Retrieve)包括Load和ListAll两种。这些方法都是框架自动完成的。
Load:根据ID标识加载对象,以及其相关对象,形成一个Object Graph,但对外是Map(对象标识是OO的基本四特征之一)。
ListAll:List该对象的所有信息,List里面的item是Map。
Insert:可以创建该主对象,如User,但也许需要创建相关对象,如Contact信息。
Update:创建对象。也可以支持不同级别的更新:更新用户信息,更新密码,更改用户角色等不同操作。像审批流程的通过和驳回,都是update操作。当然,从性能角度考虑,可以分解。
Delete:删除指定对象,以及相关对象,如删除User,其Contact也必然要删除。
任何业务对象都可以这么抽象划分并且实现,但是,复杂查询就需要单独的sql,利用MiniFramework提供的查询helper类处理,返回Map或List。

7、 敏捷开发过程
更少的代码,意味着更快的开发速度,这和敏捷过程是呼应的。现在流行的Ruby on Rails,既是一种快速开发框架,更是实践了敏捷开发的idea。MiniFramework做快速原型非常方便,而且这种原型可以直接用做后续开发。快速原型是理解需求的一大利器!
而且,我们严格要求测试驱动,分层架构为容器外测试提高了保证。
Note:个人也觉得,Rails框架比较适合于互联网开发,Java更适合企业开发。因为企业开发很重视事务处理、团队协作、可维护性、语言的简单性,某些方面是Rails所欠缺的。我现在用Rails和MiniFramework开发同一个demo,我觉得它们的开发效率相差不大。
关于语言的设计和比较,请参考书籍《Concepts of Programming Language》


MiniFramework的架构,你能够大致描述一下吗?
为了保证开发的简单、灵活性,MiniFramework在架构上做了极大的简化,方便、实用、快速是它的原则,在MiniFramework架构考虑中,我们会在常用的J2EE架构上做减法,而不是做加法。但我们会恪守几个设计的基本原则:松耦合、高内聚、职责分离。
在参考常用的架构模式和设计模式过程中,我一直在思考这个问题:为什么我需要XX模式,我可不可以不要XX模式?
下面是我认为在MiniFramework设计过程中几个核心概念:
MVC(Model 2):为什么我需要MVC?因为MiniFramework是定位在交互式的GUI应用上。经验和理论告诉我,MVC是GUI应用设计的基本原则,它保证了清晰职责分离,方便开发、测试和维护。在MVC架构模式理论中,一般遵循Change->Publish,也就是Observer模式,类似于message系统,但Web应用的本质(HTTP无状态协议,它怎么可能知道客户端的你?),可以用Request->Push(推模式),区别于Pull(拉模式)。我更倾向将MVC说成Model 2,区别于Model 1,也不同于MVC。在实际开发中,JSP是作为html模板,只被动接收Request中push过来的对象,决不主动去pull。
Note:Push和Pull,同步和异步,对软件设计很多时候有决定性的影响。
分层架构:分层架构有助于将大系统分解成子任务,每个子任务限制在一个特定的层次上,层间从上到下依赖,从下到上是松耦合。TCP/IP分层模型是它的最好证明。正如OSI 7层模型的实用模型是TCP/IP 4层模型。MiniFramework中,用户接触到的是两层:表示层和业务层,是J2EE和.NET架构的一种折中。在用MiniFramework开发时,持久层被封装起来,成为一些简单的Helper类,不是独立的一层。
之所以我去掉了持久层,只保留的dao helper,是因为,我发现业务比较简单的系统,往往开发人员喜欢在持久层里面写所有的业务,service层只是dao的一个delegate,非常 thin。要是这样,我就干脆去掉一层算了,这便是dao helper的由来。
严格的分层,可以让表示层的UI用Dreamweaver开发,业务层容器外测试,实现敏捷开发。
接口:在分层模型中,一般都非常强调接口,因为可以让上层只依赖于下层的接口,而不是实现,这样实现可以任意替换和变更,在网络开发,特别是和协议打交道的时候,我们会体会到这种设计的优雅。另外,在组件式开发中,我们也倾向于提供接口。
但是,应用MiniFramework,我们倾向于纵向开发,也就是说,某个模块从表示层到持久层都是一人开发,而不是横向:表示层的去调用业务层开发人员的业务层。这时候,纵向开发就不太适合用接口了,因为接口规范完全由本人把握。这时接口很可能只会带来臃肿,和难维护,一点改动往往牵一动百。当然,在某些情况,如开发Mock测试,Web Services,接口还是很有必要。另外,有人说,我用接口可以实现任意层替换啊?譬如我现在用Hibernate,以后换成IBatis。这完全是一个谎言,至少我看到的大多数应用,将Hibernate换成IBatis的成本绝不亚于重新开发,因为耦合太大。另外,我有个疑问:需要更换的可能性有1%吗?
个人觉得,接口比较适合于系统软件开发,而不是商业软件开发;而抽象类的继承机制比较适合商业软件开发,而不是系统软件开发。为了复用,系统软件开发倾向于组合,而不是继承。
Business Object、ActiveRecord和ORM:不同于常用J2EE开发的ORM,也不同于RoR的ActiveRecord, MiniFramework用Business Object来调用持久化的Helper类,而且它是stateless的。没有ActiveRecord的高耦合,也没有ORM的复杂性。
主要参考文献:
《Pattern-Oriented Software Architecture: Volume 1》
Model 2:http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html
《Patterns of Enterprise Application Architecture》
《Core J2EE patterns》


MiniFramework现在很完善了吗?

还是beta阶段,但是我认为对一般的项目应该够用,我已经做了完整的CRUD例子,其中有三表关联,还是有一定复杂性和代表性。
但是,我现在也在思考一个真正的企业级框架,如果说它是1.0版本的话,MiniFramework就是0.1版了,距离还很远。但我大致上思路很明确,除了以上的idea外,我还会加入以下idea和功能:
Event Driven:提高系统的可扩展性和灵活性,将Map数据作为Event的一个部分,而不是现在的全部。
Business Controller(Interceptor):相同职责统一控制,譬如权限;所有关键数据的createdTime,createdBy,updatedTime,updatedBy统一处理;Audit等。
Micro Kernel:为应用开发提供良好的适应性和扩展性,适应需求,譬如Message-based。
Service Engine:为一些常用的服务提供统一的调用方式,譬如报表系统特别强调的订单号
相关服务,如作业调度,消息系统
支持分布式协议:SOAP,RMI,
支持多种客户端:WAP,Browser,Client,PDA
对集群、安全的灵活支持
上面的很多概念并不是来源于MIS系统,但是我想将其思想引入到MiniFramework中,但还要保证MiniFramework的简单、易用。
  • cottonBusiness_code.rar (655.5 KB)
  • 描述: 包括所有代码,文章在docs目录下。
  • 下载次数: 988
    • sql.rar (1.3 KB)
    • 描述: mysql数据库脚本
    • 下载次数: 255

 

原始思路:

本来彻底是将本文删除的,    但还是考虑到最初想法的雏形,就还是贴出来,仅做备份。


1、 架构的抽象
     我先总整体上概括出一些抽象,然后从三层架构逐一说明:
* 计算机所做的任何工作,都是遵循这样一个过程:输入-》处理-》输出,大至应用架构,中至分层框架,小到对象方法、函数。
* 任何对象,对于其数据(属性),都可以用Map结构的key-》value表示。如简单的JavaBean,复杂的对象,其value是另外一个Map或List。
* 任何对象,其集合都可以表示为List。

从上面的抽象来看,我所说的架构,也完全可以看成Map输入,Map或List输出,最终的输出就是html页面。
下面,我从分层的角度再逐一抽象:

1.1 持久层
我之所以先要说持久层,是因为它不依赖于其它层,这样更容易理解。
持久层是和数据库打交道的,我所指的持久层,其实不是完整的DAO模式实现,更不是ORM,只是一些Helper类, 确切的说,只要两个Helper类,一个是QueryManager,负责Retrieve,包括read和list两个只读操作,另外一个就是PersistenceManager,负责Create、Update和Delete,也就是完整的CRUD。

* 所有的数据库操作,完全可以抽象为上面的CRUD操作。譬如审批流程的通过和驳回,都是update操作。
* 对于CRUD操作,其输入是sql语句和sql查询参数,而且,sql查询参数,其实就是一个Object数组,譬如插入Database的User表,其参数是username,password,email,age,createdTime等,age是一个Integer对象,createdTime是一个Timestamp类型。
* 对于Retrieve操作,其输出是单个对象或单个对象的集合,如loadUserById和listAllUsers,而这两者可以表示为Map和List。
* 对于其它操作,可以返回void,或int,也就是update的条数,但int也可以用Map包装。

1.2 业务层(服务层)
  业务层,也就是Service层,处理单个或复合的QueryManager+PersistenceManager,或者处理像email通知等。譬如创建一个用户,其业务流程可能是:自动为其创建账号信息,注册其blog,发送一封激活邮件,这些全部在一个事务中。
* 对于业务层,其输入就是一个Map对象,而这Map对象主要来自于Web输入。而且,可以在这个Map里面添加其它对象,如createdTime。
* sql语句,再加上sql语句的参数,就完全可以持久化一个对象,或执行查询,而该sql参数,就来自于Map输入,这个赋值过程可能需要类型转换,但很简单。
* 对于service方法执行的最终结果,如果是数据查询,就是Map或List,对于数据操作,一般是void。而该返回值,就是Action所需要的。

1.3 表示层
     表示层,我这里主要指Web层,也就是和Web服务器打交道的那部分。
     它负责调用service层的service方法,如loadUserById,将其结果返回到前端表示层页面,service可以看成MVC的M。
* Web层的输入,如创建用户的表单form,其实,就是一个键值对,而这完全可以表示为一个Map。如果对于checkbox这类输入,譬如用户的业余爱好hobby,可以看成key=hobby,value为一个字符串数组。如果查询参数只是一个id,当然就是Map的size为1了。
* Web层调用service的输出,如果是单个对象,譬如用户的个人信息,可以看成一个Map,如果是用户列表,就是用一个个Map填充的List。
* Web层Action的处理方法,如execute(),输入路径是一个url地址,输出也是一个url地址,也就是说该execute方法,是处理Map输入,而其return是一个String类型的url, 它对应一个page页面,如userDetail.jsp。但是一定要将service调用的返回值Map或List填充上。Action就是对应MVC的C。
* 结果页面负责显示Map或List数据。这也就是MVC的V的概念。Note:WebWork和模板引擎就是这么做的。

以上就是所有的抽象,总结起来,大概就是:
* 在表示层,页面表单输入Map,在action里面处理,action里面调用service层的方法,输出Map、List或void。
* Service层的service方法输入基本为页面表单的Map,转化为sql参数,然后执行sql。输出Map或List或void。
* Persistence层的Helper方法,输入sql和sql参数,输出Map、List或void。

  而上面的输入Map和输出Map或List都不用处理,不用Bean to Map,也不用Map to Bean,直来直往就可以了,而且添加、修改map里面信息也很容易。
  Map to Bean这些冗余和复杂,极易出错的行为,就是Web框架如Struts的ActionForm,Hibernate的Model几乎必备的。

2、 架构的实现
     如果上面的抽象原则大家都能够认同,那么实现就不难了,而且我们也完全可以运用成熟的第三方框架,来形成我们的整体架构。不过,单独实现,形成自己的产品,也不是很难。
     贯穿在整个架构中,有两个核心概念:弱类型和容器。弱类型我是从Javascript和Ruby语言中受启发,通过Map引入到Java中来的。容器我是借鉴Lisp语言的,因为Lisp语言的原意就是:LISt Processor。
    
     持久层的实现
     持久层,主要就是将数据库的查询出来的ResultSet,转化为Map或List。由于项目时间关系,我暂时在Spring的JDBC框架上,加工出两个Helper类,处理所有sql操作,另外,事务处理直接用Spring的声明式事务。
     对于项目开发人员,都无需了解Spring,只需要了解两个Helper类的使用就ok了,事务最后由一个人加上就ok了。也就是说,省去了大部分持久层开发,这个占项目40%左右的工作量。
    
     业务层的实现
     业务层也非常简单,就是取出Web层传入的Map某些值,组成sql参数,执行sql语句就ok了,不过sql语句可能有一定难度,但去理解由Hibernate配置文件和Model生成的sql,难度小很多,而且效率也很高,即使Hibernate有Cache机制,但用好的恐怕不多。iBatis这种和Hibernate并肩的ORM框架就是手写sql的。
    
     表示层的实现
     表示层也非常简单,因为用户输入表单提交的结果Map,我只需要一个RequestParamUtils.getInput(request) 工具方法,就可以得到,而且直接将它传给service层,省去了像Struts里面的ActionForm,那冗余的字段,get、set方法。
     表示层验证:特殊的可以用validate的Java代码,一般用Javascript就ok了,而且Javascript我会形成一个类库,很easy。我们不打算用Validation框架。如果数据验证设涉及完整性,一般考虑在Database上加约束。如果用户禁用Javascript如何?请问,我们会没事把自己的电脑设置在安全模式下吗?而且IE禁用Javascript也不容易,你试试看。别告诉我我们网站的潜在用户有用IE4.0的。
     我现在是用Webwork,不过在前一个项目中,我自己实现了一个MVC的Web框架,很好用,而且不像Struts存在线程安全的问题。之所以要用Webwork,那是我担心我的framework还需要扩展。但使用Webwork,只使用其最基本的一部分,差不多就只用到其20%功能,而且是最简单的,新手一学就会,只需要理解了打印helloworld就可以胜任了。另外,我还进行了封装,提取了一个BaseAction。
     对于action处理的结果,如Map、List对象,将之填充于Request或Session对象(BaseAction会做),通过模板技术JSTL,加上JSP展现就可以了,JSTL中的tag可以处理迭代器,日期格式显示等,而JSTL的表达式语言,加上JSP,就是模板了,可以在Dreamweave下,像html那样所见即所得开发,效率超级高。
     分页处理有本架构专门提供的分页tag,项目组成员拿来用就ok了,就如同使用html的input tag一样。
    
     本架构在本人开发的上一个项目中用到部分思想,那个项目是做150多个报表查询,约500条sql语句,这些sql语句专门由一个DBA负责(报表展现的难点在sql),我负责报表展现。实际上,我花的所有的时间不到一个月(10.8—11.6),虽然有两个月期限(另外一个月基本上就是自学其它的,如Lisp、Ruby语言),总共Java代码只有2200多行,包括一个类似于WebWork的Web Framework。也就是说平均一个页面不到15行代码。而且,后来需求引起的变更基本上可以保证半小时内搞定,因为后一个月我就是每天下午5点左右花半个小时修复修复bug,然后发布新版本。
     个人觉得,一个框架或架构的判断标准,主要是“快速开发+适应变更”,另外的附加标准是学习培训成本低。这些对于做外包项目尤为突出。asp开发部署快,学习成本低,但太难维护,特别是运行平台单一,所以逐渐被淘汰。
    
     对于Web开发,个人认为,对于产品和公司自己的项目,Java将逐渐退出其霸主地位,而会被弱类型语言,Python,特别是Ruby的Rails框架所取代,不过对于外包,这种强调团队协作,以及大型应用,Java这类强类型语言还是有其地位,因为它很容易被理解,类型就是注释,编译器检查。对于Web Service,强类型语言有其先天不足,而Web Services是未来的网络计算平台。你看Java最大的赢家IBM在干什么就知道了,它重心已经不在Java,而自觉让位于开源的JBoss。对于.net的Web开发,我觉得市场不是决定于语言有多强,而是Windows这种平台,因为我还没有发现C#比Java有多少创新,VS studio比起eclipse就不是差一个档次(不只是我这么说)。不过,在开发领域,J2EE 大概只有Servlet规范值得骄傲了,不过J2SE和J2ME还是不错。另外一种弱类型语言Javascript,随着Web2.0的兴起,Rich Client的流行,将会是一种必备语言。
     ORM,现在想来,这本身就是一种很蹩脚的东西,数据库都是关系的二维表,为什么就要转来转去的,table-》Object,Object-》table,这样很优雅?很易维护?开发更快?性能更高?我看一项都不具备。因为我们的产品,无非就是输入-》处理-》存储-》处理-》输出,为什么一定要加一个ORM层。
     领域建模,这是学习面向对象的一门必修课。但往往我们就是为了建模而建模,最后模型冗肿,实现困难,还很难维护,牵一动百,怎么去agile?领域建模,我认为主要用它来分析业务,实现未必就要ORM那套,而且,我认为最重要的是数据库E-R图,因为它是一个实实在在的东西,直接决定你的所有上层。
    
     就写到这儿了,忘了说一下,我在该架构下开发一个模块的CRUD操作5个页面,在业务清晰,数据库设计好后,开发不超过一天,工具:eclipse+Dreamweaver。
  当然,一种架构可能只能解决一类或几类问题,但架构下的思想可能解决更多的问题,因为它是超越语言的。当然,我所陈述的思想,也只是对前人的归纳总结,灵活运用罢了。
     
 

分享到:
评论
1 楼 1456996541 2008-05-13  
很好,受教了~~

相关推荐

    java三大框架

    Web MVC和Spring Web提供了Java Web应用的框架或与其他流行的Web框架进行集成。 就是说可将两者一起使用,达到将两者自身的特点进行互补。 spring 框架介绍 : 它关注的领域是其他许多流行的Framework未曾关注的...

    JAVA上百实例源码以及开源项目

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    java源码包---java 源码 大量 实例

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    JAVA上百实例源码以及开源项目源代码

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    java源码包4

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    java源码包3

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    旅游景区门户小程序是一个为游客朋友提供多元化服务的一站式数字文旅平台WeTravel.zip

    前端技术: ...Java:一种广泛用于后端开发的编程语言,常用于构建企业级应用。 Python:一种多用途编程语言,在Web开发中常用。 Ruby on Rails:一个基于Ruby编程语言的Web应用框架,提供了高效的开发工具。

    java源码包2

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java数组倒置 简单 Java图片加水印,支持旋转和透明度设置 摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印...

    SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(Spring

    简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。它可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与Swing等桌面应用程序AP组合。...

    java 面试题 总结

    exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 16、同步和异步有何异同,在什么情况下分别使用他们?举例说明。 如果数据将在线程间共享。例如正在写的数据以后可能被...

    java 编程入门思考

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 ...

    【计算机软件毕业设计】二手车交易平台的分析、设计与实现文献综述1.doc

    可以说Spring是企业应用开发的"一站式"选择,同时贯穿表现层、业务 层和持久层。Spring并没有取代那些已有的框架,而是和原有的框架进行了一次无缝地 整合。另外,Spring的用途不仅限于服务器端的开发。[4]简单来说...

    Java初学者入门教学

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 ...

    java联想(中文)

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 ...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java数组倒置 简单 Java图片加水印,支持旋转和透明度设置 摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印...

    JAVA_Thinking in Java

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 ...

    Thinking in Java简体中文(全)

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 ...

    Thinking in Java 中文第四版+习题答案

    5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 6.4...

Global site tag (gtag.js) - Google Analytics