Eclipse Rich Client Platform (RCP) 以插件架構聞名,但插件間的服務查找與依賴管理往往導致強耦合。本文展示如何在不侵入 RCP 核心機制(類載入器、createExecutableExtension 等)的前提下,利用 java.lang.instrument Agent + ASM 位元碼操作 + Annotation,實現透明的 Setter 注入,讓開發者僅需標註 @Serviceable、@Injected 即可完成依賴綁定。
ServiceLocator 掃描目標物件的所有方法,尋找 @Injected 標註,從擴展點 com.onjava.servicelocator.servicefactory 註冊的 IServiceFactory 取得服務實例並反射呼叫 Setter。支援選填依賴(optional=true)與遞迴初始化(服務本身也是可服務物件)。
IOCTransformer 實作 ClassFileTransformer,在 premain 註冊。載入類時:
ClassAnnotationVisitor 檢查是否有 @ServiceableConstructorVisitor 收集所有建構子ClassConstructorWriter 在每個建構子開頭插入 ServiceLocator.service(this) 呼叫關鍵 ASM 指令:
mv.visitVarInsn(ALOAD, 0); // 載入 this
mv.visitMethodInsn(INVOKESTATIC, // 呼叫靜態方法
"com/onjava/servicelocator/ServiceLocator",
"service", "(Ljava/lang/Object;)V");
IFortuneCookie 介面FortuneServiceFactory 實作 IServiceFactory,於 plugin.xml 註冊@Serviceable,Setter 標註 @Injected 注入 IFortuneCookie服務釋放策略、循環依賴檢測、Mock 服務單元測試整合等留待後續研究。