转载

JavaWeb Project Review

工作5年了,加上参加课外培训班和实习,接触Java7年了。从最开始的struts,到现在spring cloud,原来搭建个Web Project,即使再熟悉也得个把小时,如果遇上升级别人搭建的项目要升级,由于一套javaee框架的组成部分各自迭代,一行业务逻辑不动,也得折腾个几天。今天看spring boot 2.0,发现velocity从1.5版本开始已经不支持,不是deprecated,而是removed。感慨spring这么多年来的强大,总结下自己眼中的java web的发展。

1、洪荒初生

大三的时候,2011年,那个时候理解的web project,就是一个提供服务的项目,没有spring,没有struts,没有tomcat,甚至没有数据库。那时候的参考资料只有java教材一套,上面都是些java基础,例如java io分为字符流和字节流,然后怎么怎么实现,教材应该是以java 1.5或者java 1.6为前提的。老师布置了一个聊天软件的作业,就是简单的聊天工具,一个人说话,另外一个人能够收到。按理来说,这不是一个web project项目,可实际上,他是一个cs结构的工程,分为client和server,server端的处理可以看成是没有view层的一个web project。。项目的代码以前留了下来, https://github.com/MarsYoung/FreeTalk ,看了看,代码结构是这个样子。

JavaWeb Project Review JavaWeb Project Review

这是当时画的一个图,因为当时server端和client是合在一起写的,最后发现这两个耦合的太严重,最后都不知道写到哪里去了。后来画图整理思路,拆了一段时间,终于把项目分为了两部分。server端的服务,最初只有一个线程,监听某个socket,读取字符流,刚开始测试发现都ok,client发送的消息客户端收到了。但很快就出现了,当有两个客户端启动的时候,第二个就连不上,因为端口被别的client占用了。那个时候java都没有nio的概念,操作系统也刚开始学,自然想到了最暴力的处理方式,新建多个socket监听,于是就有了上图的server端。每有一个用户注册或者登录进来,生成一个和用户绑定的新的线程,启动一个新端口监听。这里没有线程池,连数据层也是直接写到普通file中取得,但是一个server就这样实现了,client的数据通过socket直接发送到了服务端,并在服务端处理。最开始,server的实现在我眼中就是这么粗旷,没有spring factory,没有线程池,没有业务层和数据层的划分,没有数据库,也没什么server容器。。

2、初次下山

学校里做的,和社会脱节还是比较严重的。大三学期,在外面接触到了当时最流行的web框架,SSH。Struts2,Spring,Hibernate。其实得感谢外包行业,是这波企业由于需要大量的开发人员,把这些优秀的框架带给了与社会脱节的学校。Struts2,是从Struts发展而来,变化也特别大,如下图:

Feature

Struts 1

Struts 2

Action classes

Struts1 extends the abstract base class by its action class. The problem with struts1 is that it uses the abstract classes rather than interfaces.

While in Struts 2, an Action class implements an Action interface, along with other interfaces use optional and custom services. Struts 2 provides a base ActionSupport class that implements commonly used interfaces. Although an Action interface is  not necessary, any POJO object along with an execute signature can be used as an Struts 2 Action object.

Threading Model

Struts 1 Actions are singletons therefore they must be thread-safe because only one instance of a class handles all the requests for that Action. The singleton strategy restricts to Struts 1 Actions and requires extra care to make the action resources thread safe or synchronized while developing an application.

Struts 2 doesn't have thread-safety issues as Action objects are instantiated for each request. A servlet container generates many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.

Servlet Dependency

Actions are dependent on the servlet API because HttpServletRequest and HttpServletResponse is passed to the execute method when an Action is invoked therefore Struts1.

Container does not treat the Struts 2 Actions as a couple. Servlet contexts are typically represented as simple Maps that allow Actions to be tested in isolation. Struts 2 Actions can still access the original request and response, if required. While other architectural elements directly reduce or eliminate the need to access the HttpServetRequest or HttpServletResponse.

Testability

Struts1 application has a major problem while testing the application because the execute method exposes the Servlet API. Struts TestCase provides a set of mock object for Struts 1.

To test the Struts 2 Actions instantiate the Action, set the properties, and invoking methods. Dependency Injection also makes testing easier.

Harvesting Input

Struts 1 recieves an input by creating an ActionForm object. Like the action classes, all ActionForms class must extend a ActionForm base class. Other JavaBeans classes cannot be used as ActionForms, while developers create redundant classes to receive the input. DynaBeans is the best alternative to create the conventional ActionForm classes.

Struts 2 requires Action properties as input properties that eliminates the need of a second input object. These Input properties may be rich object types, since they may have their own properties. Developer can access the Action properties from the web page using the taglibs. Struts 2 also supports the ActionForm pattern, POJO form objects and POJO Actions as well.

Expression Language

Struts1 integrates with JSTL, so it uses the JSTL EL. The EL has basic object graph traversal, but relatively weak collection and indexed property support.

Struts 2 can use JSTL, but the framework also supports a more powerful and flexible expression language called "Object Graph Notation Language" (OGNL).

Binding values into views

Struts 1 binds objects into the page context by using the standard JSP mechanism.

Struts 2 uses a ValueStack technology to make the values accessible to the taglibs without coupling the view to the object to which it is rendering. The ValueStack strategy enables us to reuse views across a range of types, having same property name but different property types.

Type Conversion

Struts 1 ActionForm properties are almost in the form of Strings. Commons-Beanutils are used by used by Struts 1 for type conversion. Converters are per-class, which are not configurable per instance.

Struts 2 uses OGNL for type conversion and converters to convert Basic and common object types and primitives as well.

Validation

Struts 1 uses manual validation that is done via a validate method on the ActionForm, or by using an extension to the Commons Validator. Classes can have different validation contexts for the same class, while chaining to validations on sub-objects is not allowed.

Struts 2 allows manual validation that is done by using the validate method and the XWork Validation framework. The Xwork Validation Framework allows chaining of validations into sub-properties using the validations defined for the properties class type and the validation context.

Control Of Action Execution

Each module in Struts 1 has a separate Request Processors (lifecycles), while all the Actions in the module must share the same lifecycle.

In Struts 2 different lifecycles are created on a per Action basis via Interceptor Stacks. Custom stacks are created and used with different Actions, as

总结下,就是struts1过时了,sturts2中Action类从继承改成了更方便的实现接口,数据从actionForm改成了pojo,线程从单利不安全改成了多态安全的,标签支持了ognl等等。Spring用的是3.*版本的,hibernate也是3.*版本的。这时的jar包还是通过一个lib文件夹导入的。启动入口也是web.xml。这种结构大概是这个样子。

JavaWeb Project Review JavaWeb Project Review

JavaWeb Project Review

JavaWeb Project Review

3、练气6层

毕业后,SSH用多了之后,大家都觉得太臃肿了。首先是替换hibernate,风靡一时的ssb,即把hibernate换成了mybatis。mybatis从 apache ibatis3 fork而来。mybatis有一些hibernate的优点,如简化原生的crud,不用每次都去操心数据库连接了,不用专门去管理session了,对象可以直接映射到数据库,而且还有缓存。同时mybatis还更方便的支持了sql,让优化更方便和简单。另一方面,hibernate的专属hql还是需要学一学的。也有些项目,感觉直接用jpa做持久化更方便,直接面向sql,也更容易上手。同时,在读多写少数据上,采用了memcache和redis各种缓存。也有采用redis集群,hbase,mongo,cassandra等直接存储数据。

其次呢,是struts2,有换成jersey的,有换成spring mvc的,有换成jboss resteasy的。struts2不是restful的,而spring mvc不仅是restful 的,而且更容易和spring整合。jersey和jboss resteasy都是严格意义上restful风格的。

对于cms系统之类呢,也从struts的ognl表达式的应用,jsp换成了各种模版渲染,velocity,freemarker等。

再次,从容器上看,glassfish,jetty,resin等也开始和tomcat争辉。都有从一个独立的进程,变成嵌入式的趋势。

JavaWeb Project Review

4、练气9层

大数据的潮流,一个个游戏App的昙花一现,或是微信,视频,网购,美颜,拼车,外卖,头条等像病毒一样附着在每个用户的手机上,不同的业务场景,背后都是动辄成百上千万的日访问量,对于技术来说,一方面,以nginx作为负载均衡的架构,后面挂一堆服务的结构已经变得难以管理。上百个的项目,耦合,与业务迭代恶性循环。淘宝,当当,国内的开发人员,设计了dubbo等soa架构的分布式管理框架。而队列、缓存、NoSQL、大数据分析、业务监控也成为互联网公司的标配。

JavaWeb Project Review

5、结丹

spring boot的发展,让开发一个web项目再简单不过。点击下鼠标就能把之前几乎所有的架构搭建出来。spring cloud的发展,成了开源的分布式架构非常不错的选择。而struts2,velocity等技术似乎已经过气,流行着的是undertow,thymeleaf。

服务开始更加的容易实现,也容易扩展和解耦。微服务的架构也普及开来。

http://start.spring.io/

6、5维空间。

原文  https://blog.csdn.net/mshootingstar/article/details/79841948
正文到此结束
Loading...