如何在ByteBuddy转换器中识别生成类并跳过Spring包装类
ByteBuddy 跳过动态生成类的解决方案
我们在JavaAgent中使用ByteBuddy实现了如下转换器,但希望跳过Spring生成的动态包装类这类动态生成的类型。推测这类类的class.getProtectionDomain().getCodeSource()会返回null,但不知道如何在ByteBuddy中实现该检查:
new AgentBuilder.Default() .type(TypeMatchers.create(Configuration.getInstance())) .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { try { AnnotationDescription digmaMarkerAnnotationDescription = getDigmaMarkerAnnotationDescription(); return builder .visit(new MemberAttributeExtension.ForMethod() .annotateMethod(digmaMarkerAnnotationDescription) .on(MethodMatchers.create(typeDescription, Configuration.getInstance()))); } catch (Throwable e) { Log.error("got exception in bytebuddy transformer", e); return builder; } }).installOn(inst);
解决方案
ByteBuddy的AgentBuilder支持通过filter()方法添加类过滤逻辑,你可以直接利用转换器参数中的protectionDomain完成CodeSource检查,同时也可以结合动态生成类的其他特征增强过滤效果。
1. 基础实现:检查CodeSource是否为null
在type()匹配阶段之后添加filter(),跳过CodeSource为null的类:
new AgentBuilder.Default() .type(TypeMatchers.create(Configuration.getInstance())) // 过滤掉CodeSource为null的动态生成类 .filter((typeDescription, classLoader, module, protectionDomain) -> { if (protectionDomain == null) { return false; } return protectionDomain.getCodeSource() != null; }) .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { try { AnnotationDescription digmaMarkerAnnotationDescription = getDigmaMarkerAnnotationDescription(); return builder .visit(new MemberAttributeExtension.ForMethod() .annotateMethod(digmaMarkerAnnotationDescription) .on(MethodMatchers.create(typeDescription, Configuration.getInstance()))); } catch (Throwable e) { Log.error("got exception in bytebuddy transformer", e); return builder; } }).installOn(inst);
2. 增强过滤:结合Spring动态类特征
除了CodeSource检查,还可以通过类名特征、接口实现情况精准识别Spring生成的代理类:
new AgentBuilder.Default() .type(TypeMatchers.create(Configuration.getInstance())) .filter((typeDescription, classLoader, module, protectionDomain) -> { // 跳过CodeSource为null的类 if (protectionDomain != null && protectionDomain.getCodeSource() == null) { return false; } String className = typeDescription.getTypeName(); // 跳过Spring CGLIB生成的增强类和FastClass if (className.contains("$$EnhancerBySpringCGLIB$$") || className.contains("$$FastClassBySpringCGLIB$$")) { return false; } // 跳过实现Spring CGLIB Factory接口的类 return !typeDescription.isAssignableTo(org.springframework.cglib.proxy.Factory.class); }) .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { try { AnnotationDescription digmaMarkerAnnotationDescription = getDigmaMarkerAnnotationDescription(); return builder .visit(new MemberAttributeExtension.ForMethod() .annotateMethod(digmaMarkerAnnotationDescription) .on(MethodMatchers.create(typeDescription, Configuration.getInstance()))); } catch (Throwable e) { Log.error("got exception in bytebuddy transformer", e); return builder; } }).installOn(inst);
内容的提问来源于stack exchange,提问作者Shin938
相关产品推荐
相关产品推荐

