规则可以通过指定自定义帮助类来扩展、覆盖或替换内置调用。例如,在以下规则中,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 HelperSub
RULE helping hand
...
RULE I can't help myself
...
HELPER YellowSub
RULE help, I need somebody
CLASS ...
METHOD ...
...
前两条规则使用 HelperSub
,第三条规则使用 YellowSub
。
帮助类支持生命周期方法,用于在规则加载和卸载时执行初始化和清理操作。这些方法包括:
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 确保生命周期方法按照帮助类继承层次链式调用:
activated
和 installed
。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 原创精华