假設我想將 應用于@Advice.OnMethodEnter中聲明的方法org.springframework.web.context.support.GenericWebApplicationContext。為此,我編寫了這個最小代理:public class SequenceAgent { public static void premain(final String args, final Instrumentation instrumentation) { new AgentBuilder.Default() .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager()) .type(nameStartsWith( "org.springframework.web.context.support.GenericWebApplicationContext")) .transform((builder, typeDescription, classLoader, module) -> builder .method(any()).intercept(Advice.to(SequenceAdvice.class))) .installOn(instrumentation); } public static class SequenceAdvice { @Advice.OnMethodEnter static void enter(@Advice.This Object thiz, @Advice.Origin Method method, @Advice.AllArguments Object... args) { String className = thiz.getClass().getName(); String methodName = method.getName(); System.out.println("Entered: " + className + "#" + methodName); } }}我希望此配置被過濾掉org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext,因為它不匹配org.springframework.web.context.support.GenericWebApplicationContext,但看起來對此類對象的方法調用也被攔截:import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;public class AgentTest { public static void main(String[] args) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); context.containsBean("SomeBean"); }}當附加到代理并運行時,它會打印出來(為了便于閱讀而包裝):Entered: org.springframework.boot.web.servlet.context. AnnotationConfigServletWebServerApplicationContext #getResourcePatternResolver...Entered: org.springframework.boot.web.servlet.context. AnnotationConfigServletWebServerApplicationContext #getResourceCache
1 回答

一只甜甜圈
TA貢獻1836條經驗 獲得超5個贊
字節好友使用 String.startsWith。
您所看到的是由于 Byte Buddy 檢測類,而不是實例。在某種程度上,想想 Byte Buddy 將通知代碼復制到目標方法中。
結果,所有子類都會受到影響。為了做你正在做的事情,你需要在調用期間檢查實例類的類型,就像你想在 Java 中實現它一樣。
添加回答
舉報
0/150
提交
取消