使用父类匹配时,如何编写ElasticApmInstrumentation匹配器仅捕获子类构造方法?
解决方案:仅匹配子类构造方法
要解决子类构造调用super()导致的重复触发问题,核心思路是只拦截父类的子类构造方法,排除父类自身的构造方法,以下是几种可行的实现方式:
方式一:类匹配器直接过滤父类
先通过类匹配器锁定所有继承自目标父类的类型,但明确排除父类本身,再搭配构造方法匹配器:// 类匹配器:匹配所有继承自YourParentClass的子类(不含父类) ElementMatcher<? super TypeDescription> classMatcher = isSubtypeOf(YourParentClass.class) .and(not(is(YourParentClass.class))); // 构造方法匹配器:仅匹配上述子类的构造方法 ElementMatcher<? super MethodDescription> constructorMatcher = isConstructor();方式二:在构造方法匹配器中判断声明类
把子类判断逻辑整合到构造方法匹配器里,直接检查当前构造方法所属的类是否为父类的子类且不等于父类:ElementMatcher<? super MethodDescription> constructorMatcher = isConstructor().and(method -> { TypeDescription declaringClass = method.getDeclaringType(); return declaringClass.isSubtypeOf(YourParentClass.class) && !declaringClass.equals(TypeDescription.ForLoadedType.of(YourParentClass.class)); });方式三:基于类名的精准过滤
如果无法直接引用父类的Class对象,可通过类的全限定名来匹配和排除:String parentClassName = "com.yourpackage.YourParentClass"; ElementMatcher<? super TypeDescription> classMatcher = hasSuperType(named(parentClassName)) .and(not(named(parentClassName)));
上述方案本质都是避免匹配父类的构造方法,这样子类调用super()时,父类构造方法不会被当前instrumentation拦截,自然就不会出现同一对象多次触发的问题。
内容的提问来源于stack exchange,提问作者pTrik
相关产品推荐
相关产品推荐

