懷舊框架集合
最近在公司用JUP框架做項目,發現這個框架是別人基于SpringSide封裝的,所以打算學習下,SpringSide,其中遇到了很多坑,做個記錄,網上關于這方面的資料都有些老了,而且SpringSide最新的版本是SpringSide-Utils,老一點的版本為v4.2.2.GA,以下分別對這兩個版本分別介紹下,主要內容來自于網上。
一些資料:
Github源碼地址: https://github.com/springside/springside4
OSchina源碼地址: https://git.oschina.net/calvin1978/springside4
官方文檔: https://github.com/springside/springside4/wiki
SpringSide網址: http://springside.github.io/
1、SpringSide簡介
SpringSide--Pragmatic Enterprise Application KickStart and Common Library Stack,這么長的一個名字下來,不用解釋大家都知道是做什么的了----以Spring Framework為core,提供一個Pragmatic的企業應用開發基礎以及企業應用中各主題的最佳實踐展示。
愿景:為使用Spring框架的開發者提供一個非Demo版的復雜、正式而體現最佳使用實踐的參照系統。為JavaEEer必須面對的問題提供合乎Pragmatic原則的解決方案。
SpringSide的四個部分--
Springside-Bookstore: 一個Full Feature的書店示例,兼有書店前臺和后臺管理,作為典型企業應用的微縮版。
SpringSide-Core :SpringSide封裝的核心代碼。
SpringSide-Templates: 讓用戶可以快速復制粘貼構建出自己應用的代碼模版,分Application與Plugins兩部分。
SpringSide-Generator: 自動整合SpringSide-Application/Plugins生成項目,生成CRUD代碼的Eclipse Plugins 和Ant 腳本。
來看看SpringSide的作者,江南白衣的對它的介紹:
SpringSide是什么?為什么要發起這個項目?
SpringSide是以Spring Framework為核心的,Pragmatic風格的JavaEE應用參考示例,是Java世界中的主流技術選型,最佳實踐的總結與演示。因為基于Spring也因為對Spring理念的認同,項目起名SpringSide,另外還有個好記的中文名字——“春天的旁邊”。
想起做這個項目,是在六七年前元旦輾轉反側的夜晚,想著自己應該為世界留下點什么。寫一本書還是做一個開源項目呢? 總感覺書印出來了就沒法改了,對我這種完美主義者有點難受。而開源項目,就可以永遠年輕,永遠生長,永遠重構……
然后,做什么項目呢?那時候,淘寶們還沒有開始大規模開源自己的技術。國內的原創框架更多是在自娛自樂。所以SprinSide選了一條更低端的路線,將那時候已經太多而不是太少的開源項目粘合在一起,用好,也算是一樁功德了。
SpringSide包含哪些演示項目? 這些項目采用或演示了哪些技術?
SpringSide里含有QuickStart 與 Showcase 一小一大兩個示例項目。
QuickStart是一個迷你的TodoList應用,濃縮了一個普通JavaEE應用所需的柴米油鹽各種基礎技術,從典型的CRUD界面,到趕時髦的Rest API,以及最基礎的用戶管理功能,可以作為很多項目的初始骨架。
Showcase 則一個五花八門的JavaEE技術大雜燴大派對,如安全、緩存、日志、消息中間件、定時任務等等等等。
SpringSide 4和之前版本相比,有哪些較大改進?
SSH 與 SSH2 發展到高潮后,Spring也進入了一個后Spring的時代,受到各種新興語言與框架如Play! Framework的圍攻。SpringSide 4,演示的就是這個后Spring時代的演進,如何使得avaEE依然是個體面的選擇。
一些變動包括 DAO框架轉用Spring Data JPA + Hibernate, MVC框架轉用Spring MVC 3, Restful框架轉用Spring MVC + Spring RestTemplate, CSS框架轉用Twitter Bootstrap,安全框架轉用Apache Shiro 等等,Selenium升級到WebDriver。
所有變動的目標,都是在代碼越來越簡單的同時,也保持對工業化大規模開發的支持。比如有些新興語言框架,高手自己可以寫得很快,但不一定適合很多普通程序員一起合作開發與維護。所以有些過度簡化的演進,比如完全拋棄XML純用Annotation的ApplicationContext定義方式,SpringSide并沒有使用。
如何基于SpringSide創建新的項目?
SpringSide也是利用Maven的Archetype插件來創建新項目的,在每次版本發布時都會把前面所說的QuickStart項目打包成一個模板項目。用戶只要用標準的maven archetype指令,就可以基于QuickStart項目生成自己的項目。
SpringSide采用什么開源協議?對商用有什么限制?
用的是所知最開放的Apache License2,任何的Copy&Paste都是歡迎的。如果有哪個更開放的告訴我吧,因為實在對靠開源賺錢沒有過任何想法。
有沒有其他開發者參與貢獻?
4.0這個大版本暫時只有我一個在主導。不過github真的是一個非常社交化的開源平臺,沒有了sourceforge、google code那種固定的開發團隊的概念。現在誰都可以闖進SpringSide來,改它幾行代碼,然后向我發起一個Pull Request就可以了。題外話,像Nutz那樣精細的貢獻者記錄,真是值得表揚又讓人羨慕的事情。
SpringSide的發布周期?未來的發展方向?
項目堅持了六七年,四個大版本,期間服務器遷徙數次,也有過多次跳票的不良記錄。所以很難說出一個固定的發布周期來。最近自己比較希望能做到與白天的項目一樣,固定三周一個的迭代,但也并不總能如愿。希望大家能相信我的人品,項目或遲或早,總是會發布的……
至于未來的發展方向,一方面會繼續做細JavaEE普通應用的演示,使它與一般的玩具型演示項目有更顯眼的區別。一方面會展示更多互聯網項目的新潮技術,如NoSQL、ZooKeeper等,畢竟這看起來更有趣。
2、SpringSide4技術選型
以下是對SpringSide-Utils的一個簡單介紹:
1.SpringSide-Utils簡介
把在唯品會兩年的實踐抽取出來,做一個大大大的公共類庫。一邊封裝 Guava 和 Apache Common Lang,一邊參考移植各門各派的精華:
專門的類庫:Jodd, Apache Common IO,Common Collections,JCTool,OpenHFT,AndroidUtilCode
大廠的開源類庫:Facebook JCommon,twitter commons,linkedin-utils
內庫中包含了文本、數字、日期、并發、集合、文件、反射、安全等方面的內容等著大家一一探索,這里又再嘮叨一下性能,性能,性能。
新庫的設計目標,是把最佳實踐都封裝起來,讓大家使用類庫時,默認就獲得最優的性能。
2.日期
2.1 DateFormatUtil
日期與String相互轉換時,JDK的SimpleDateFormat,又慢,又非線程安全。
在不能全面轉為Joda Time時,使用Common Lang的FastDateFormat,又快,又線程安全,還能緩存實例。
2.2 CachingDateFormatter
FastDateFormat再快,日期格式化還是個消耗很大的事情。
參考Logback和Log4j2,在打印當前時間的場景里,將同一時刻的結果緩存。
3. 文本
3.1 StringBuilderHolder
ThreadLocal地重用StringBuilder,節約長字符串拼接時的內存消耗,節約成倍復制擴容的CPU消耗,是OpenHFT等好幾個類庫的共同選擇。
3.2 HashUtil
ThreadLocal地重用SHA1的MessageDiggest,減少每次創建MessageDigest的消耗,也是Tomcat,Facebook等好幾個類庫的共同選擇。
3.3 JsonMapper
封裝Jackson的實現,并提供不序列化“值為NULL的屬性”等選擇。
3.4 TextValidator
判斷是否合法的電話,身份證之類的正則表達式校驗,Pattern必須得預先編譯而不要每次創建,但總有匆忙的同學忘記這點。
3.5 MoreStringUtil
Common Lang的StringUtils已經很好用了。不過字符串操作的消耗總是很大,這里針對一些操作,給出更極致的性能優化,比如split()。
4. 集合
4.1 原子類型集合
當集合中的元素是原子類型,而不是對象的時候。直接以原子類型來存儲,不但節約內存(int vs Integer, 4 bytes vs 16 bytes),甚至內部的數據結構也能完全不一樣,從而大幅提高性能。
從Netty中移植了IntOjbectHashMap 和 LongObjectHashMap,性能約提升50%。后面還會有IntArrayList等等。
4.2 MapUtil, ListUtil ...
各種集合類的Util的創建函數,強迫大家去思考Array Base 集合類的初始大小,避免了容量不足時的成倍擴容; HashMap的加載因子,減少哈希沖突。
在集合為空或只有一個元素時,使用Java Collections的特殊數據結構,進一步節約內存。
4.3 其他擴展類型
1. Guava
MuitlSet :as MapCounter,不用再自己處理“如果有就+1,沒有就放個元素進去”的煩事
MultiMap: as MultiValueMap
WeakConcurrentHashMap: 鍵值為弱引用的并發Map,只此一家
RangeMap:定義一段范圍的Key,對應一個Value,類似一致性哈希環之類的最合適
2. Common Collections:
UniqueArrayList
MultiKeyMap
Flat3Map:如果少于3個元素直接訪問屬性,否則才訪問真正的HashMap
3. Jodd
SortedArrayList
4. JCTools
針對 “多個生產者一個消費者”, “一個生產者多個消費者” 等特定場景優化的Queue。
5. 并發
5.1 JSR166e
JDK的不同版本,不斷推出性能更優的并發實現,但如果考慮多JDK版本到的兼容就讓人發愁了。好在有Doug Lea大神的JSR166e項目。
1. ThreadLocalRandom
Random本身有全局鎖,JDK7的ThreadLocalRandom通過在ThreadLocal里放Random避免了鎖。
2. LongAdder
作為計數器,AtomicLong雖然能通過CAS避免鎖,但如果線程競爭激烈時依然有很大的損耗。JDK8的LongAdder,根據并發情況,將計數器智能的拆開成若干個,等取值時再求和。
3. ConcurrentHashMapV8
JDK5開始的ConcurrentHashMap是經典的分散鎖模式,而JDK8的ConcurrentHashMap,優化后居然取消了鎖。
5.2 ThreadPoolBuilder
比JDK Executors,提供更好的線程池設置,比如FixedPool的隊列最大長度,CachedPool的最大線程數等。
另提供一個從Tomcat移植的QueueableCachedPool,“支持可變的線程數,跑滿線程時任務放隊列”這種符合大家想想的場景。
5.3 ThreadLocalContext
提供ThreadLocal HashMap存放上下文的示例,并給出更高效的,使用EnumMap的建議。
6. 反射
6.1 BeanMapper
基于orika封裝,同時避免了一些低效API的使用,比如不給出來源集合的類型,讓框架自己去反射"iterator"函數的返回值來獲取類型的惡劣行為。
更給出了預生成Type類型的最高效的用法。
6.2 FastMethodInvoker
基于cglib,通過代碼生成實現最快速的反射調用。比如反射調用A類的“hello” 方法,它就直接生成一個調用a.hello()的FastMethod子類.
7. 其他
7.1 ExceptionUtil
異常構造時,獲取當前Stack Trace是一個很耗時的過程,把Stack Trace打印也同樣消耗。
如果是一個比較清楚出處的異常,可以通過static定義的靜態異常。
但如果異常的message會變化,就不能靜態定義唯一的異常了,此時可使用克隆異常,依然避過構造函數。
7.2 SystemPropertiesUtil
Properties本質上是一個有鎖的HashTable,所以不能頻繁的調用System.getProperty()。提供了一個以回調方式獲取變化的ListenableProperties。
posted on 2020-10-09 19:14 paulwong 閱讀(309) 評論(0) 編輯 收藏 所屬分類: SPRING