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