自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

遠(yuǎn)程熱部署在美團(tuán)的落地實(shí)踐

原創(chuàng) 精選
開發(fā) 架構(gòu)
Sonic是美團(tuán)內(nèi)部研發(fā)設(shè)計(jì)的一款用于熱部署的IDEA插件,本文其實(shí)現(xiàn)原理及落地的一些技術(shù)細(xì)節(jié)。

作者 | 凱哥 占峰 李晗等

Sonic是美團(tuán)內(nèi)部一款用于熱部署的IDEA插件。本文主要講述Sonic的實(shí)現(xiàn)細(xì)節(jié)以及底層原理,從IDEA插件到自動化部署,再到沉浸式開發(fā)產(chǎn)品閉環(huán),全方位講述了Sonic在美團(tuán)的落地與實(shí)踐經(jīng)驗(yàn)。目前業(yè)界對標(biāo)的產(chǎn)品并不多,希望本文能對從事聯(lián)調(diào)/開發(fā)/測試等相關(guān)方向的同學(xué)有所幫助或啟發(fā)。

Sonic是美團(tuán)內(nèi)部研發(fā)設(shè)計(jì)的一款用于熱部署的IDEA插件,本文其實(shí)現(xiàn)原理及落地的一些技術(shù)細(xì)節(jié)。在閱讀本文之前,建議大家先熟悉一下Spring源碼?、Spring MVC 源碼 、Spring Boot源碼 、Agent字節(jié)碼增強(qiáng)?、Javassist?、Classloader等相關(guān)知識。?

1 前言

1.1 什么是熱部署

所謂熱部署,就是在應(yīng)用正在運(yùn)行時升級軟件,卻不需要重新啟動應(yīng)用。對于Java應(yīng)用程序來說,熱部署就是在運(yùn)行時更新Java類文件,同時觸發(fā)Spring以及其他常用第三方框架的一系列重新加載的過程。在這個過程中不需要重新啟動,并且修改的代碼實(shí)時生效,好比是戰(zhàn)斗機(jī)在空中完成加油,不需要戰(zhàn)斗機(jī)熄火降落,一系列操作都在“運(yùn)行”狀態(tài)來完成。

1.2 為什么我們需要熱部署

據(jù)了解,美團(tuán)內(nèi)部很多工程師每天本地重啟服務(wù)高達(dá)5~12次,單次大概3~8分鐘,每天向Cargo(美團(tuán)內(nèi)部測試環(huán)境管理工具)部署3~5次,單次時長20~45分鐘,部署頻繁頻次高、耗時長,嚴(yán)重影響了系統(tǒng)上線的效率。而插件提供的本地和遠(yuǎn)程熱部署功能,可讓將代碼變更“秒級”生效。一般而言,開發(fā)者日常工作主要分為開發(fā)自測和聯(lián)調(diào)兩個場景,下面將分別介紹熱部署在每個場景中發(fā)揮的作用。

圖 1

1.2.1 開發(fā)自測場景

一般來講,在用插件之前,開發(fā)者修改完代碼還需等待3~8分鐘啟動時間,然后手動構(gòu)造請求或協(xié)調(diào)上游發(fā)請求,耗時且費(fèi)力。在使用完熱部署插件后,修改完代碼可以一鍵增量部署,讓變更“秒級”生效,能夠做到快速自測。而對于那些無法本地啟動項(xiàng)目,也可以通過遠(yuǎn)程熱部署功能使代碼變更“秒級”生效。

圖 2

1.2.2 聯(lián)調(diào)場景

通常情況下,在使用插件之前,開發(fā)者修改代碼經(jīng)過20~35分鐘的漫長部署,需要聯(lián)系上游聯(lián)調(diào)開發(fā)者發(fā)起請求,一直要等到遠(yuǎn)程服務(wù)器查看日志,才能確認(rèn)代碼生效。在使用熱部署插件之后,開發(fā)者修改代碼遠(yuǎn)程熱部署能夠秒級(2~3s)生效,開發(fā)者直接發(fā)起服務(wù)調(diào)用,可以節(jié)省大量的碎片化時間(熱部署插件還具備流量回放、遠(yuǎn)程調(diào)用、遠(yuǎn)程反編譯等功能,可配合進(jìn)行使用)。

圖 3

所以,熱部署插件希望解決的痛點(diǎn)是:在可控的條件內(nèi),幫助開發(fā)者減少頻繁編譯部署的次數(shù),節(jié)省碎片化的時間。最終為開發(fā)者每天節(jié)約出一定量的編碼時間。

1.3 熱部署難在哪

為什么業(yè)界目前沒有好用的開源工具?因?yàn)闊岵渴鸩坏韧跓嶂貑?,像Tomcat或者Spring Boot DevTools此類熱重啟模式需要重新加載項(xiàng)目,性能較差。增量熱部署難度較大,需要兼容常用的中間件版本,需要深入啟動銷毀加載流程。以美團(tuán)為例,我們需要對JPDA(Java Platform Debugger Architecture)、Java Agent、ASM字節(jié)碼增強(qiáng)、Classloader、Spring框架、Spring Boot框架、MyBatis框架、Mtthrift(美團(tuán)RPC框架)、Zebra(美團(tuán)持久層框架)、Pigeon(美團(tuán)RPC框架),MDP(美團(tuán)快速開發(fā)框架)、XFrame(美團(tuán)快速開發(fā)腳手架)、Crane(美團(tuán)分布式任務(wù)調(diào)度框架)等眾多框架和技術(shù)原理深入了解才能做到全面的兼容和支持。另外,還需要IDEA插件開發(fā)能力,形成整體的產(chǎn)品解決方案閉環(huán),美團(tuán)的熱部署插件Sonic正是在這種背景下應(yīng)運(yùn)而生。

圖 4

1.4 Sonic可以做什么

Sonic是美團(tuán)內(nèi)部研發(fā)設(shè)計(jì)的一款I(lǐng)DEA插件,旨在通過低代碼開發(fā)輔助遠(yuǎn)程/本地?zé)岵渴?,解決Coding、單測編寫執(zhí)行、自測聯(lián)調(diào)等階段的效率問題,提高開發(fā)者的編碼產(chǎn)出效率。數(shù)據(jù)統(tǒng)計(jì)表明,開發(fā)者日常大概有35%時間用于編碼的產(chǎn)出。如果想提高研發(fā)效率,要么擴(kuò)大編碼產(chǎn)出的時間占比,要么提高編碼階段的產(chǎn)出效率,而Sonic則聚焦提高編碼階段的產(chǎn)出效率。目前,使用Sonic熱部署可以解決大部分代碼重復(fù)構(gòu)建的問題。Sonic可以使用戶在本地編寫代碼一鍵部署到遠(yuǎn)程環(huán)境,修改代碼、部署、聯(lián)調(diào)請求、查看日志,循環(huán)反復(fù)。如果不考慮代碼修改時間,通常一個循環(huán)需要20~35分鐘,而使用Sonic可以把整個時長縮短至5~10秒,而且能夠給開發(fā)者帶來高效沉浸式的開發(fā)體驗(yàn)。在實(shí)際編碼工作中,多文件修改是家常便飯,Sonic對多文件的熱部署能力尤為突出,它可以通過依賴分析等手段來對多文件批量進(jìn)行遠(yuǎn)程熱部署,并且支持Spring Bean Class、普通Class、Spring XML、MyBatis XML等多類型文件混合熱部署。下面的動圖就演示了多文件復(fù)查場景下的增量熱部署:

那么跟業(yè)界現(xiàn)有的產(chǎn)品相比,Sonic有哪些優(yōu)劣勢呢?下面我們嘗試給出幾種產(chǎn)品的對比,僅供大家參考:

上表未把Sofa-Ark、Osgi、Arthas列舉,此類屬于插件化、模塊化應(yīng)用框架,以及Java在線診斷工具,核心能力非熱部署。值得注意的是,Spring Boot DevTools只能應(yīng)用在Spring Boot項(xiàng)目中,并且它不是增量熱部署,而是通過Classloader迭代的方式重啟項(xiàng)目,對大項(xiàng)目而言,性能上是無法接受的。雖然,JRebel支持三方插件較多,生態(tài)龐大,但是對于國產(chǎn)的插件不支持,例如FastJson等,同時它還存在遠(yuǎn)程熱部署配置局限,對于公司內(nèi)部的中間件需要個性化開發(fā),并且是商業(yè)軟件,整體的使用成本較高。

1.5 Sonic遠(yuǎn)程熱部署落地推廣的實(shí)踐經(jīng)驗(yàn)

相信大家都知道,對于技術(shù)產(chǎn)品的推廣,尤其是開發(fā)、測試階段使用的產(chǎn)品,由于遠(yuǎn)離線上環(huán)境,推動力、執(zhí)行力、產(chǎn)品功能閉環(huán)能否做好,是決定著該產(chǎn)品是否能在企業(yè)內(nèi)部落地并得到大多數(shù)人認(rèn)可的重要的一環(huán)。此外,因?yàn)楹芏嚅_發(fā)者在開發(fā)、測試階段已逐漸形成了“固化動作”,如何改變這些用戶的行為,讓他們擁抱新產(chǎn)品,也是Sonic面臨的艱巨挑戰(zhàn)之一。我們從主動溝通、零成本(或極低成本)快速接入、自動化腳本,以及產(chǎn)品自動診斷、收集反饋等方向出發(fā),踐行出了四條原則。

圖 6

2 整體設(shè)計(jì)方案

2.1 Sonic結(jié)構(gòu)

Sonic插件由4大部分組成,包括腳本端、插件端、Agent端,以及Sonic服務(wù)端。腳本端負(fù)責(zé)自動化構(gòu)建Sonic啟動參數(shù)、服務(wù)啟動等集成工作;IDEA插件端集成環(huán)境為開發(fā)者提供更便捷的熱部署服務(wù);Agent端隨項(xiàng)目啟動負(fù)責(zé)熱部署的功能實(shí)現(xiàn);服務(wù)端則負(fù)責(zé)收集熱部署信息、失敗上報(bào)等統(tǒng)計(jì)工作。如下圖所示:

圖 7

2.2 走進(jìn)Agent

2.2.1 Instrumentation類常用API

public interface Instrumentation {

    //增加一個Class 文件的轉(zhuǎn)換器,轉(zhuǎn)換器用于改變 Class 二進(jìn)制流的數(shù)據(jù),參數(shù) canRetransform 設(shè)置是否允許重新轉(zhuǎn)換。
    void addTransformer(ClassFileTransformer transformerboolean canRetransform);

    //在類加載之前,重新定義 Class 文件,ClassDefinition 表示對一個類新的定義,
    //如果在類加載之后,需要使用 retransformClasses 方法重新定義。addTransformer方法配置之后,后續(xù)的類加載都會被Transformer攔截。
    //對于已經(jīng)加載過的類,可以執(zhí)行retransformClasses來重新觸發(fā)這個Transformer的攔截。類加載的字節(jié)碼被修改后,除非再次被retransform,否則不會恢復(fù)。
    void addTransformer(ClassFileTransformer transformer);

    //刪除一個類轉(zhuǎn)換器
    boolean removeTransformer(ClassFileTransformer transformer);
    
    //是否允許對class retransform
    boolean isRetransformClassesSupported();

    //在類加載之后,重新定義 Class。這個很重要,該方法是1.6 之后加入的,事實(shí)上,該方法是 update 了一個類。
    void retransformClasses(Class<?>... classesthrows UnmodifiableClassException;
   
    //是否允許對class重新定義
    boolean isRedefineClassesSupported();

    //此方法用于替換類的定義,而不引用現(xiàn)有的類文件字節(jié),就像從源代碼重新編譯以進(jìn)行修復(fù)和繼續(xù)調(diào)試時所做的那樣。
    //在要轉(zhuǎn)換現(xiàn)有類文件字節(jié)的地方(例如在字節(jié)碼插裝中),應(yīng)該使用retransformClasses。
    //該方法可以修改方法體、常量池和屬性值,但不能新增、刪除、重命名屬性或方法,也不能修改方法的簽名
    void redefineClasses(ClassDefinition... definitionsthrows  ClassNotFoundExceptionUnmodifiableClassException;

    //獲取已經(jīng)被JVM加載的class,有className可能重復(fù)(可能存在多個classloader)
    @SuppressWarnings("rawtypes")
    Class[] getAllLoadedClasses();
}



2.2.2 Instrument簡介

Instrument的底層實(shí)現(xiàn)依賴于JVMTI(JVM Tool Interface),它是JVM暴露出來的一些供用戶擴(kuò)展的接口集合,JVMTI是基于事件驅(qū)動的,JVM每執(zhí)行到一定的邏輯就會調(diào)用一些事件的回調(diào)接口(如果存在),這些接口可以供開發(fā)者去擴(kuò)展自己的邏輯。JVMTIAgent是一個利用JVMTI暴露出來的接口提供了代理啟動時加載(Agent On Load)、代理通過Attach形式加載(Agent On Attach)和代理卸載(Agent On Unload)功能的動態(tài)庫。而Instrument Agent可以理解為一類JVMTIAgent動態(tài)庫,別名是JPLISAgent(Java Programming Language Instrumentation Services Agent),也就是專門為Java語言編寫的插樁服務(wù)提供支持的代理。

2.2.3 啟動時和運(yùn)行時加載Instrument Agent過程

圖 8

2.3 那些年JVM和HotSwap之間的“相愛相殺”

圍繞著Method Body的HotSwap JVM一直在進(jìn)行改進(jìn)。從1.4版本開始,JPDA引入HotSwap機(jī)制(JPDA Enhancements),實(shí)現(xiàn)Debug時的Method Body的動態(tài)性。大家可參考文檔:??enhancements1.4???。1.5版本開始通過JVMTI實(shí)現(xiàn)的java.lang.instrument(Java Platform SE 8)的Premain方式,實(shí)現(xiàn)Agent方式的動態(tài)性(JVM啟動時指定Agent)。大家可參考文檔:??package-summary???。1.6版本又增加Agentmain方式,實(shí)現(xiàn)運(yùn)行時動態(tài)性(通過The Attach API 綁定到具體VM)。大家可參考文檔:??package-summary?? ?;緦?shí)現(xiàn)是通過JVMTI的retransformClass/redefineClass進(jìn)行method、body級的字節(jié)碼更新,ASM、CGLib基本都是圍繞這些在做動態(tài)性。但是針對Class的HotSwap一直沒有動作(比如Class添加method、添加field、修改繼承關(guān)系等等),為什么會這樣呢?因?yàn)閺?fù)雜度過高,且沒有很高的回報(bào)。

2.4 Sonic如何解決Instrumentation的局限性

由于JVM限制,JDK 7和JDK 8都不允許改類結(jié)構(gòu),比如新增字段,新增方法和修改類的父類等,這對于Spring項(xiàng)目來說是致命的。比如開發(fā)同學(xué)想修改一個Spring Bean,新增一個@Autowired字段,此類場景在實(shí)際應(yīng)用時很多,所以Sonic對此類場景的支持必不可少。那么,具體是如何做到的呢?這里要提一下“大名鼎鼎”的Dcevm。Dcevm(DynamicCode Evolution Virtual Machine)是Java Hostspot的補(bǔ)?。▏?yán)格上來說是修改),允許(并非無限制)在運(yùn)行環(huán)境下修改加載的類文件。當(dāng)前虛擬機(jī)只允許修改方法體(Method,Body),而Decvm可以增加、刪除類屬性、方法,甚至改變一個類的父類,Dcevm是一個開源項(xiàng)目,遵從GPL 2.0協(xié)議。更多關(guān)于Dcevm的介紹,大家可以參考:??Wuerthinger10a???以及??GitHub Decvm???。值得一提的是,在美團(tuán)內(nèi)部,針對Dcevm的安裝,Sonic已經(jīng)打通??HULK??,集成發(fā)布鏡像即可完成(本地?zé)岵渴鹂山Y(jié)合插件功能實(shí)現(xiàn)一鍵安裝熱部署環(huán)境)。

3 Sonic熱部署技術(shù)解析

3.1 Sonic整體架構(gòu)模型

上一章節(jié)我們主要介紹了Sonic的組成。下圖詳細(xì)介紹了Sonic在運(yùn)行期間各個組成部分的工作職責(zé),由它們形成一整套完備的技術(shù)產(chǎn)品落地閉環(huán)方案:

圖 9

3.2 Sonic功能流轉(zhuǎn)

Sonic通過NIO監(jiān)聽本地文件變更,觸發(fā)文件變更事件,例如Class新增、Class修改、Spring Bean重載等事件流程。下圖展示了一次熱部署單個文件的生命周期:

圖 10

3.3 文件監(jiān)聽

Sonic首先會在本地和遠(yuǎn)程預(yù)定義兩個目錄,??/var/tmp/sonic/extraClasspath???和??/var/tmp/sonic/classes??。extraClasspath為Sonic自定義的拓展Classpath URL,classes為Sonic監(jiān)聽的目錄,當(dāng)有文件變更時,通過IDEA插件來部署到遠(yuǎn)程/本地,觸發(fā)Agent的監(jiān)聽目錄,來繼續(xù)下面的熱加載邏輯:

圖 11

為什么Sonic不直接替換用戶ClassPath下面的資源文件呢?因?yàn)榭紤]到業(yè)務(wù)方WAR包的API項(xiàng)目、Spring Boot、Tomcat項(xiàng)目、Jetty項(xiàng)目等,都是以JAR包來啟動的,這樣是無法直接修改用戶的Class文件的。即使是用戶項(xiàng)目可以修改,直接操作用戶的Class,也會帶來一系列的安全問題。所以,Sonic采用拓展ClassPath URL路徑來實(shí)現(xiàn)文件的修改和新增。并且存在這么一種場景,多個業(yè)務(wù)側(cè)的項(xiàng)目引入相同的JAR包,在JAR里面配置MyBatis的XML和注解。在此類情況下,Sonic沒有辦法直接來修改JAR包中源文件,通過拓展路徑的方式可以不需要關(guān)注JAR包,來修改JAR包中某一文件和XML。同理,采用此類方法可以進(jìn)行整個JAR包的熱替換。下面我們簡單介紹一下Sonic的核心監(jiān)聽器,如下圖所示:

圖 12

3.4 JVM Class Reload

JVM的字節(jié)碼批量重載邏輯,通過新的字節(jié)碼二進(jìn)制流和舊的Class對象生成ClassDefinition定義,instrumentation.redefineClasses(definitions),來觸發(fā)JVM重載,重載過后將觸發(fā)初始化時Spring插件注冊的Transfrom。接下來,我們簡單講解一下Spring是怎么重載的。新增class Sonic如何保證可以加載到Classloader上下文中?由于項(xiàng)目在遠(yuǎn)程執(zhí)行,所以運(yùn)行環(huán)境復(fù)雜,有可能是JAR包方式啟動(Spring Boot),也有可能是普通項(xiàng)目,也有可能是War Web項(xiàng)目,針對此類情況Sonic做了一層Classloader URL拓展。

圖 13

User ClassLoader是框架自定義的ClassLoader統(tǒng)稱,例如Jetty項(xiàng)目是WebAppclassLoader。其中Urlclasspath為當(dāng)前項(xiàng)目的lib文件件下,例如Spring Boot項(xiàng)目也是從當(dāng)前項(xiàng)目BOOT-INF/lib/路徑中加載CLass等等,不同框架的自定義位置稍有不同。所以針對此類情況,Agent必須拿到用戶的自定義Classloader,如果是常規(guī)方式啟動的,比如普通Spring XML項(xiàng)目,借助Plus(美團(tuán)內(nèi)部服務(wù)發(fā)布平臺)發(fā)布,此類沒有自定義Classloader,是默認(rèn)AppClassLoader,所以Agent在用戶項(xiàng)目啟動過程中,借助字節(jié)碼增強(qiáng)的方式來獲取到真正的用戶Classloader。

圖 14

找到用戶使用的子Classloader之后,通過反射的方式來獲取Classloader中的元素Classpath,其中ClassPath中的URL就是當(dāng)前項(xiàng)目加載Class時需要的所有運(yùn)行時Class環(huán)境,并且包括三方的JAR包依賴等。Sonic獲取到URL數(shù)組,把Sonic自定義的拓展Classpath目錄加入到URL數(shù)組首位,這樣當(dāng)有新增Class時,Sonic只需要將Class文件復(fù)制到拓展Classpath對應(yīng)的包目錄下面即可,當(dāng)有其他Bean依賴新增的Class時,會從當(dāng)前目錄下面查找類文件。為什么不直接對Appclassloader進(jìn)行加強(qiáng)?而是對框架的自定義Classloader進(jìn)行加強(qiáng)?

圖 15

考慮這樣一個場景,框架自定義類加載器中有ClassA,此時用戶新增ClassB需要熱加載,B Class里面有A的引用關(guān)系,如果增強(qiáng)AppClassLoader,初始化B實(shí)例時ClassLoader。loadclass首先從UserClassLoader開始加載ClassB的字節(jié)碼,依靠雙親委派原則,B被Appclassloader加載,因?yàn)锽依賴類A,所以當(dāng)前AppClassLoader加載B一定是加載不到的,此時會拋出ClassNotFoundException異常。所以對類加載器拓展,一定要拓展最上層的類加載器,這樣才會達(dá)到使用者想要的效果。

3.5 Spring Bean重載

Spring Bean Reload過程中,Bean的銷毀和重啟流程,主要內(nèi)容如下圖展示:

圖 16

首先當(dāng)修改Java Class D時,通過Spring ClasspathScan掃描校驗(yàn)當(dāng)前修改的Bean是否Sprin Bean(注解校驗(yàn)),然后觸發(fā)銷毀流程(BeanDefinitionRegistry.removeBeanDefinition),此方法會將當(dāng)前Spring上下文中的Bean D和依賴Spring Bean D的Bean C一并銷毀,但是作用范圍僅僅在當(dāng)前Spring上下文。如果C被子上下文中的Bean B依賴,就無法更新子上下文中的依賴關(guān)系,當(dāng)有系統(tǒng)請求時,Bean B中關(guān)聯(lián)的Bean C還是熱部署之前的對象,所以熱部署失敗。因此,在Spring初始化過程中,需要維護(hù)父子上下文的對應(yīng)關(guān)系,當(dāng)子上下文變時若變更范圍涉及到Bean B時,需要重新更新子上下文中的依賴關(guān)系,當(dāng)有多上下文關(guān)聯(lián)時需要維護(hù)多上下文環(huán)境,且當(dāng)前上下文環(huán)境入口需要Reload。這里的入口是指:Spring MVC Controller、Mthrift和Pigeon,對不同的流量入口,采用不同的Reload策略。RPC框架入口主要操作為解綁注冊中心、重新注冊、重新加載啟動流程等等,對Spring MVC Controller,主要是解綁和注冊URL Mappping來實(shí)現(xiàn)流量入口類的變化切換。

3.6 Spring XML重載

當(dāng)用戶修改/新增Spring XML時,需要對XML中所有Bean進(jìn)行重載。

圖 17

重新Reload之后,將Spring銷毀后重啟。需要注意的是:XML修改方式改動較大,可能涉及到全局的AOP的配置以及前置和后置處理器相關(guān)的內(nèi)容,影響范圍為全局,所以目前只放開普通的XML Bean標(biāo)簽的新增/修改,其他能力酌情逐步放開。

3.7 MyBatis 熱部署

Spring MyBatis熱部署的主要處理流程是在啟動期間獲取所有Configuration路徑,并維護(hù)它和Spring Context的對應(yīng)關(guān)系,在熱部署Class、XML時去匹配Configuration,從而重新加載Configuration以達(dá)到熱部署的目的。

圖 18

4 總結(jié)

4.1 熱部署功能一覽

上一章節(jié)主要講述了Spring Bean、Spring MVC、MyBatis的重載流程,Sonic還支持其它常用的開發(fā)框架,豐富的框架支持和兼容能力是Sonic的基石,下面列舉一些Sonic支持的常用的第三方框架:

圖19

美團(tuán)內(nèi)部框架以及常用開源框架截止目前,Sonic已經(jīng)支持絕大部分常用第三方框架的熱加載,常規(guī)業(yè)務(wù)開發(fā)幾乎無需重啟服務(wù)。并且在美團(tuán)內(nèi)部的成功率已經(jīng)高達(dá)99.9%以上,真正地讓熱部署來代替常規(guī)部署構(gòu)建成為一種可能。

4.2 IDE插件集成

Sonic也提供了功能強(qiáng)大的IDEA插件,讓用戶進(jìn)行沉浸式開發(fā),遠(yuǎn)程熱部署也變得更加便利。

圖 20

4.3 推廣使用情況

截止到發(fā)稿時,Sonic在美團(tuán)使用人數(shù)3000+,應(yīng)用項(xiàng)目數(shù)量2000+。該項(xiàng)目還獲得了美團(tuán)內(nèi)部2020年下半年到家研發(fā)平臺“最佳效率團(tuán)隊(duì)”獎。

5 作者簡介

凱哥、占峰、李晗、龔炎、程驍、玉龍等,均來自美團(tuán)/到家研發(fā)平臺。

6 參考文章

?[1] 基于Javassist和Javaagent實(shí)現(xiàn)動態(tài)切面[2] Spring MVC 源碼解析[3] Spring IOC源碼解析[4] MyBatis源碼解析[5] Spring Boot源碼解析[6] Spring AOP源碼解析[7] Spring事務(wù)源碼解析[8] Cglib源碼解析[9] JDK Proxy源碼解析[10] Dcevm簡介[11] 字節(jié)碼增強(qiáng)技術(shù)探索[12] Javassist API

責(zé)任編輯:張燕妮 來源: 美團(tuán)技術(shù)團(tuán)隊(duì)
相關(guān)推薦

2022-08-09 09:18:47

優(yōu)化實(shí)踐

2024-03-20 14:22:55

遠(yuǎn)程熱部署

2018-07-13 09:53:27

移動應(yīng)用美團(tuán)代碼

2022-03-25 10:47:59

架構(gòu)實(shí)踐美團(tuán)

2022-04-15 15:46:06

數(shù)據(jù)視頻技術(shù)

2019-08-23 13:10:39

美團(tuán)點(diǎn)評Kubernetes集群管理

2018-10-29 15:50:23

深度學(xué)習(xí)工程實(shí)踐技術(shù)

2022-03-15 10:20:00

云原生系統(tǒng)實(shí)踐

2018-06-01 10:08:00

DBA美團(tuán)SQL

2017-02-20 19:23:13

2017-07-20 17:27:01

互聯(lián)網(wǎng)

2022-04-15 10:30:03

美團(tuán)技術(shù)實(shí)踐

2022-08-12 12:23:28

神經(jīng)網(wǎng)絡(luò)優(yōu)化

2023-11-14 12:07:43

美團(tuán)沙龍

2018-03-28 09:53:50

Android架構(gòu)演進(jìn)

2022-02-14 16:08:15

開源項(xiàng)目線程池動態(tài)可監(jiān)控

2022-06-17 11:54:17

數(shù)據(jù)模型系統(tǒng)

2022-04-29 09:10:00

算法人工智能技術(shù)

2018-10-19 14:16:09

Flink數(shù)據(jù)倉庫數(shù)據(jù)系統(tǒng)

2013-08-20 13:11:58

技術(shù)美團(tuán)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號