用
spring
,註解是個繞不開的話題。spring-boot
中常用@RestController
與@Controller
來分置api
與web
開發。yii與其思路一致,以不同名稱空間下的控制器yii\rest\ActiveController
及yii\web\Controller
,達到差異化控制。為了最小侵入式,spring-boot
經常使用依賴注入+動態代理,而非是強引用關係的繼承,最典型的莫過於webmvc
中controller
設計
核心容器
Core Container
由spring-core , spring-beans , spring-context , spring-context-support
和spring-expression
(Spring表示式語言)模組組成
Context ( spring-context )
模組構建在Core and Beans
模組提供的堅實基礎之上,新增對國際化(例如,使用資源包),事件傳播,資源載入以及透過例如Servlet容器透明建立上下文的支援.spring-context-support
支援將常見的第三方庫整合到Spring
應用程式上下文中,用於快取,郵件(JavaMail
),排程(CommonJ,Quartz
)和模板引擎(FreeMarker,JasperReports,Velocity
)spring-expression
用於在執行時查詢和操作物件圖,命名變數以及從Spring
的IoC
容器中按名稱檢索物件,列表投影和選擇以及常用列表聚合
註解處理流程(JSR269
提案)
- 編譯器把原始碼解析生成AST抽象語法樹
- 註解處理器階段
- 分析和生成,此時前兩步完成後,生成位元組碼(進行型別擦除)
註解處理方式
- 執行時反射機制
Java
提供的API
來處理編譯期的註解
javac編譯過程
- 解析和填充符號表
- 解析Parser 詞法分析 語法分析
- 插入式註解處理器的註解處理
- jdk1.6+ 插入式註解標準API開發
- 編譯期插入式註解處理器對註解進行處理
- 分析與位元組碼生成
位元組碼增強
Java位元組碼增強指的是在Java位元組碼生成之後,對其進行修改
- 修改位元組碼 在記憶體中獲取到原來的位元組碼,然後透過一些工具(如 ASM,Javaasist)來修改它的byte[]陣列
- 使修改後的位元組碼生效
- 方式一:自定義
ClassLoader
來載入修改後的位元組碼 - 替換掉原來的位元組碼:在
JVM
載入使用者的Class
時,攔截,返回修改後的位元組碼,或者在執行時,使用Instrumentation.redefineClasses
方法來替換掉原來的位元組碼
- 方式一:自定義
java動態代理
JDK的
java.lang.reflect.Proxy
實現InvocationHandler
介面 動態代理。spring
的動態代理使用位元組碼增強,實現了兩種代理方式,jdk介面動態,cglib
繼承動態。代理策略,基於目標類有否實現介面類,有則預設使用jdk動態代理。沒有但強制使用cglib,則用繼承式代理。
- 動態代理核心 將分散的對物件不同方法的呼叫轉發到一個同一的處理函式中
- 動態代理實現AOP 即在執行函式前和執行函式後都能執行自己定義的鉤子
- 實現RPC
- PRC本質將函式呼叫方和函式的提供方分散在兩個不同的程式上
- 中間使用網路通訊來進行資料互動,RPC呼叫其實是對遠端另外一臺機器程式上的物件的代理
- 處理中心將呼叫的資訊封裝打包,透過網路傳送給另外一個程式
JVM 類載入步驟
- 載入 透過類的全限定名獲取到類的二進位制流
- 驗證 確保Class 檔案的位元組流中包含的資訊符合虛擬機器的要求
- 準備 為類變數分配記憶體空間並設定類變初始值
- 解析
- 初始化 根據使用者指定的程式碼初始化欄位和其他資源, 執行 static 塊
Class.forName(className, true, currentLoader)
預設 獲取到 Class 物件時, 會自動對類進行初始化ClassLoader.loadClass
並不會初始化類,因此類中的靜態程式碼塊不會執行
元配置資訊
- bean定義本質上是用於建立一個或多個物件的配方
- Bean及其之間的依賴關係反映在容器使用的配置後設資料中
- 配置後設資料以 XML,Java註解或Java程式碼(java類)表示
無論是何種形式的配置,在容器內部是
BeanDefinition
例項來描述依賴
Bean依賴管理
spring
提供了一系列Aware
介面 ,允許bean向容器指示它們需要某種基礎結構依賴性
介面列表與已注入的依賴關係
ApplicationContextAware
宣告應用上下文ApplicationEventPublisherAware
封裝事件釋出者BeanClassLoaderAware
用於載入bean類的類載入器BeanFactoryAware
宣告 BeanFactoryBeanNameAware
宣告bean的名稱BootstrapContextAware
資源介面卡,通常僅在JCA中可用LoadTimeWeaverAware
定義的weaver(織入)用於在載入時處理類定義MessageSourceAware
用於解析訊息的已配置策略NotificationPublisherAware
Spring JMX通知釋出商PortletConfigAware
當前 PortletConfig 容器執行PortletContextAware
ResourceLoaderAware
用於對資源進行低階訪問ServletConfigAware
ServletContextAware
本作品採用《CC 協議》,轉載必須註明作者和本文連結