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,看了看,代碼結構是這個樣子。
    
這是當時畫的一個圖,因爲當時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 notnecessary, 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。這種結構大概是這個樣子。


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爭輝。都有從一個獨立的進程,變成嵌入式的趨勢。


4、練氣9層
大數據的潮流,一個個遊戲App的曇花一現,或是微信,視頻,網購,美顏,拼車,外賣,頭條等像病毒一樣附着在每個用戶的手機上,不同的業務場景,背後都是動輒成百上千萬的日訪問量,對於技術來說,一方面,以nginx作爲負載均衡的架構,後面掛一堆服務的結構已經變得難以管理。上百個的項目,耦合,與業務迭代惡性循環。淘寶,噹噹,國內的開發人員,設計了dubbo等soa架構的分佈式管理框架。而隊列、緩存、NoSQL、大數據分析、業務監控也成爲互聯網公司的標配。


5、結丹
spring boot的發展,讓開發一個web項目再簡單不過。點擊下鼠標就能把之前幾乎所有的架構搭建出來。spring cloud的發展,成了開源的分佈式架構非常不錯的選擇。而struts2,velocity等技術似乎已經過氣,流行着的是undertow,thymeleaf。
服務開始更加的容易實現,也容易擴展和解耦。微服務的架構也普及開來。
http://start.spring.io/
6、5維空間。


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章