1.編譯期(預處理),用的是apt,通過編譯器javac的-processor參數,指定註解預處理類,對程序進行修改。
這個時期可以做的事情,可以通過解析原程序生成的抽象語法樹(AST)來創建新的源程序。
日本比較有名的orm框架doma2用的就是這種方法,比如自動實例化Dao interface生成實例化後的源文件。
也可以對抽象語法數(AST)進行修改,編譯成新的class。
Lombok就是這樣做的。
可以參照這個網頁看看Lombok的運行原理
https://my.oschina.net/wangmengjun/blog/821976
2.編譯期,這個必須用自定義的編譯器,而不是標準的javac。
自定義的編譯器裏,會根據額外的配置和處理,把一個java源文件編譯成一個增強了的類文件。
aspectj的ctw模式用的就是這個方法
3.類加載,用的是javaagent,通過java的-javaagent參數,指定代理類,在加載類的時候,對類進行動態修改。
由於類加載的時候,就完成了修改,所以不管以什麼方式創建實例的時候,用的都是修改後的類
aspectj的ltw模式就是用的這個方法
4.創建實例,這裏不能用new關鍵字去創建了,一般是通過一個類容器來創建,容器裏對再對類進行改造,創建一個代理類(有interface的時候)的實例,或者創建一個子類(沒有interface的時候)的實例。也就是說實際上類的實例已經不是原來那個類的了。
spring的proxy模式用的就是這個方法