使用者定義的規則與 Helper
Helper
規則可以透過指定自定義幫助類來擴充套件、覆蓋或替換內建呼叫。例如,在以下規則中,FailureTester
被用作幫助類,其布林例項方法 doWrongState(CoordinatorEngine)
決定是否丟擲 WrongStateException
。
# 幫助示例
RULE help yourself
CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
METHOD commit
HELPER com.arjuna.wst11.messaging.engines.FailureTester
AT EXIT
IF doWrongState($0)
DO throw new WrongStateException()
ENDRULE
幫助類要求
自定義幫助類需滿足以下條件:
-
不可宣告為
final
:允許 Byteman 進行子類化。 - 不可為抽象類:需支援例項化。
-
提供公共建構函式:
- 預設使用空建構函式(
()
)。 - 如果存在建構函式
(org.jboss.byteman.agent.rule.Rule)
,Byteman 優先呼叫。
- 預設使用空建構函式(
透過繼承預設Helper
,可以擴充套件或覆蓋其方法。例如:
# 幫助示例 2
RULE help yourself but rely on others
CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
METHOD commit
HELPER HelperSub
AT ENTRY
IF NOT flagged($this)
DO debug("throwing wrong state");
flag($this);
throw new WrongStateException()
ENDRULE
自定義Helper
:
class HelperSub extends Helper {
public HelperSub(Rule rule) {
super(rule);
}
public boolean debug(String message) {
super.debug("!!! IMPORTANT EVENT !!! " + message);
return true;
}
}
上述規則可使用預設幫助類的 flag
和 flagged
方法,同時為 debug
新增自定義行為。
多規則的 Helper 配置
在規則檔案中,可以透過新增 HELPER
行指定後續規則的預設 Helper:
HELPER HelperSub
RULE helping hand
...
RULE I can't help myself
...
HELPER YellowSub
RULE help, I need somebody
CLASS ...
METHOD ...
...
前兩條規則使用 HelperSub
,第三條規則使用 YellowSub
。
Helper 生命週期方法
幫助類支援生命週期方法,用於在規則載入和解除安裝時執行初始化和清理操作。這些方法包括:
public static void activated()
public static void deactivated()
public static void installed(Rule rule)
public static void installed(String ruleName)
public static void uninstalled(Rule rule)
public static void uninstalled(String ruleName)
生命週期事件
Byteman 提供了一套靈活的生命週期鉤子方法,允許開發者在規則載入和解除安裝時執行特定的操作。這些方法包括:
-
activated
:當規則集合從空變為非空時觸發,適用於執行一次性初始化操作,例如初始化資源或設定環境變數。 -
deactivated
:當規則集合從非空變為空時觸發,適用於釋放資源或清理狀態,例如關閉連線或重置配置。 -
installed
:當規則載入時觸發,適用於針對規則執行特定設定,例如註冊監聽器或初始化規則相關的資料結構。 -
uninstalled
:當規則解除安裝時觸發,適用於清理與規則相關的資源,例如登出監聽器或釋放記憶體。
如果幫助類實現了上述方法,Byteman 會在規則載入和解除安裝時自動呼叫這些鉤子。例如,activated()
會在第一個規則載入時呼叫,而 deactivated()
則會在最後一個規則解除安裝時呼叫。透過這些生命週期鉤子,開發者可以更好地管理規則的初始化和清理過程,確保系統的穩定性和資源的高效利用。
生命週期方法呼叫鏈
Byteman 確保生命週期方法按照幫助類繼承層次鏈式呼叫:
-
安裝事件:從規則 Helper 類開始,向上呼叫
activated
和installed
。 -
解除安裝事件:從 Helper 超類開始,向下呼叫
uninstalled
和deactivated
。
目標類與觸發類
規則的 CLASS
或 INTERFACE
子句定義規則的目標類或介面,規則可注入多個目標類。以下情況可能發生:
-
目標類名匹配多個類:如規則
CLASS Foo
可能被注入到org.my.Foo
和org.acme.Foo
。 -
目標類與子類的匹配:如規則
CLASS ^Foo
可能被注入到org.my.FooBar
和org.my.FooBaz
。 -
介面匹配實現類:如規則
INTERFACE Foo
可能被注入到實現介面的類。
型別檢查可透過兩種模式控制:
-
AS TARGET
(詞法範圍):型別檢查基於目標型別。例如:AS TARGET IF $0.append($2)
若目標型別
List
不定義append
方法,將導致型別檢查失敗。 AS TRIGGER
(動態範圍,預設):型別檢查基於注入點的動態觸發類,可支援子類的特定方法。
在規則檔案中,可以透過 AS TARGET
或 AS TRIGGER
明確指定型別檢查模式,從而更精確地控制規則的行為和適用範圍。AS TARGET
模式用於指定規則的目標型別,即規則所作用的物件或資料,適用於需要對目標物件進行嚴格型別檢查的場景,例如資料驗證或物件屬性約束;而 AS TRIGGER
模式則用於指定規則的觸發型別,即觸發規則執行的條件或事件,適用於需要對觸發條件進行型別檢查的場景,例如事件驅動規則或條件觸發邏輯。透過這兩種模式,開發者可以更靈活地定義規則,確保型別安全性和邏輯正確性,從而提升系統的可靠性和可維護性。
規則編譯
預設情況下,規則由 Byteman 的直譯器執行,但也可以編譯為位元組碼以提高效能。透過以下方式控制規則的編譯行為:
- 設定全域性預設模式:
- 使用系統屬性:org.jboss.byteman.compile.to.bytecode
。
- 在規則檔案中透過 COMPILE
或 NOCOMPILE
指定。
-
單個規則編譯: 在規則中新增
COMPILE
子句:RULE compile example CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine METHOD prepare COMPILE AT ENTRY ... ENDRULE
-
控制規則組模式:
COMPILE RULE example 1 ... ENDRULE NOCOMPILE RULE example 2 ... ENDRULE
-
COMPILE
:強制編譯。 -
NOCOMPILE
:強制使用解釋模式。
透過靈活設定編譯模式,可平衡效能和規則載入開銷。
FunTester 原創精華
【連載】從 Java 開始效能測試
- 混沌工程、故障測試、Web 前端
- 服務端功能測試
- 效能測試專題
- Java、Groovy、Go
- 白盒、工具、爬蟲、UI 自動化
- 理論、感悟、影片