jOOQ星期二:拉斐尔·温特豪德(Rafael Winterhalter)正在与字节好友搏斗字节码
歡迎來到jOOQ Tuesdays系列。 在本系列中,我們每隔一個月的第三個星期二發(fā)布一篇文章,從jOOQ的角度采訪我們發(fā)現(xiàn)該行業(yè)令人興奮的人。 這包括從事SQL,Java,開放源代碼以及其他各種相關主題的人員。
我們很高興在第七版中與Rafael Winterhalter進行交談,他將向我們介紹Java字節(jié)代碼的深度以及他的庫Byte Buddy,該庫使使用字節(jié)碼的工作變得非常容易 。
請注意,Byte Buddy贏得了2015年“杜克選擇獎” -對此我們表示祝賀!
字節(jié)好友的作用是什么?
字節(jié)好友是一個代碼生成和操作庫。 它提供了一些API,這些API可在運行時創(chuàng)建新的Java類以及在加載之前或之后更改現(xiàn)有的類。
乍一看,這聽起來似乎很深奧,但是運行時代碼生成已在許多Java項目中使用。 庫開發(fā)人員通常使用代碼生成工具來實現(xiàn)面向方面的編程。 例如, 模擬庫Mockito使用Byte Buddy在運行時創(chuàng)建模擬類的子類。 為了實現(xiàn)模擬,Mockito會覆蓋類的所有方法,以便在測試中調用某個方法時,不會調用用戶的原始代碼。 還有許多其他知名的代碼生成用戶。 例如,Spring使用代碼生成來實現(xiàn)其注釋方面,例如安全性或事務。 而且Hibernate使用代碼生成方法,通過覆蓋那些getter來僅在調用它們的情況下才通過查詢來延遲從getter方法中加載屬性。
當有諸如ASM,CGLIB,AspectJ或Javassist之類的替代方案時,為什么需要Byte Buddy?
在開始從事Byte Buddy的工作之前,我曾作為貢獻者參與了其他幾個開源項目。 如前所述,代碼生成是實現(xiàn)許多庫的典型要求,因此我習慣了使用CGLIB和Javassist 。 但是,我對這些庫的局限性不斷感到沮喪,我想解決我發(fā)現(xiàn)的問題。 最終,我開始寫一個替代庫,后來以Byte Buddy的形式發(fā)布。
要了解備用庫的局限性,模擬是一個很好的示例用例。 Mockito中的小樣以前是使用CGLIB創(chuàng)建的。 CGLIB是一個相當成熟的庫。 它已經(jīng)存在了15年以上,當它最初被開發(fā)時,圖書館的開發(fā)人員當然并沒有想到諸如注釋,通用類型或防御方法之類的功能。 但是,注釋確實成為許多不接受模擬實例的API的重要組成部分,因為所有重寫方法的注釋都會丟失。 在Java中,方法的注釋在被覆蓋時永遠不會繼承。 并且類型的注釋只有在明確聲明為時才被繼承。 為了克服這個問題,Byte Buddy允許將任何注釋復制到子類中,該子類現(xiàn)在是Mockito 2中的功能。
相反,Javassist允許復制注釋,但我個人不喜歡該庫的方法。 在Javassist中,所有生成的代碼都表示為包含在字符串中的Java代碼。 結果,Javassist代碼的結構類似于非結構化的Java代碼,后者僅將SQL描述為級聯(lián)字符串。 除了創(chuàng)建難以維護的代碼外,此方法還提供了漏洞,例如類似于SQL注入的Java代碼注入。 有時可以通過允許Javassist代碼編譯任意代碼來攻擊Javassist代碼,這可能會對應用程序造成嚴重損害。
在處理現(xiàn)有代碼時, AspectJ是一個功能強大的工具。 但是,通過Byte Buddy,您可以用普通的簡單Java來執(zhí)行AspectJ能夠執(zhí)行的任何操作。 這樣,開發(fā)人員無需學習新的語法或編程隱喻,也無需為其構建過程和IDE安裝工具。 此外,我認為連接點和切入點術語并不直觀,因此決定完全避免使用。 相反,我決定模仿開發(fā)人員已經(jīng)從Java編程語言中了解的術語,以簡化Byte Buddy的第一步。
另一方面, ASM是實現(xiàn)Byte Buddy的基礎。 ASM是字節(jié)代碼解析器,而不是代碼生成庫。 ASM處理單個類文件,并且不考慮類型層次結構。 ASM既沒有類加載的概念,也沒有在字節(jié)碼指令之上包括更高級別的概念。 但是,Byte Buddy提供了一個適配器,該適配器向需要生成非常特定的代碼的用戶公開ASM API。
如何參與低級Java?
一開始,我為自己設定了僅創(chuàng)建具有注釋支持的CGLIB版本的目標,這正是我最初需要的。 但是我很快發(fā)現(xiàn),許多開發(fā)人員正在尋找Byte Buddy如今已成為的解決方案。 因此,我開始計劃使Java虛擬機的完整功能集可訪問。 為此,學習類文件格式的所有細節(jié)和極端情況已成為實現(xiàn)這些功能的必要條件。 公平地講,一旦掌握了類文件格式,它就顯得微不足道了,我真的很高興看到我的庫成熟。
您最感到在家的地方?
我想為正確的工作使用正確的工具。 顯然,我喜歡使用字節(jié)碼,但是在生產(chǎn)項目中工作時,我會避免手工制作字節(jié)碼。 最后,這是諸如Byte Buddy之類的更高級抽象的目的。
從常見的用例來看,但是Byte Buddy通常用于通過基于方法的注釋更改代碼來實現(xiàn)自定義功能。 從某種意義上說,Byte Buddy使開發(fā)人員能夠實現(xiàn)自己的4G抽象。 聲明式編程是某些任務的絕佳抽象,SQL是其中之一。
作為網(wǎng)紅,您最激動人心的故事是什么?
主要是,我很高興認識我的圖書館用戶。 我遇到了與大型團隊一起實施基于我的軟件的內部框架的人們,顯然,讓我為Byte Buddy如此有用而感到自豪。
非常感謝拉斐爾
如果您想了解有關Rafael的工作,字節(jié)碼或Byte Buddy的更多信息 ,請查看他在JavaZone上的演講:
翻譯自: https://www.javacodegeeks.com/2015/12/jooq-tuesdays-rafael-winterhalter-wrestling-byte-code-byte-buddy.html
總結
以上是生活随笔為你收集整理的jOOQ星期二:拉斐尔·温特豪德(Rafael Winterhalter)正在与字节好友搏斗字节码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 首艘国产大型邮轮“爱达・魔都号”用上 5
- 下一篇: 红帽JBoss企业应用平台7.0 ALP