Java ByteBuddy';s ElementMatchers#名称开始使用?

Java ByteBuddy';s ElementMatchers#名称开始使用?,java,byte-buddy,javaagents,Java,Byte Buddy,Javaagents,假设我想对org.springframework.web.context.support.GenericWebApplicationContext中声明的方法应用@Advice.OnMethodEnter。为此,我编写了一个最小代理: 公共类SequenceAgent{ public static void premain(最终字符串参数, 最终仪表(仪表){ 新建AgentBuilder.Default() .with(new AgentBuilder.InitializationStrate

假设我想对
org.springframework.web.context.support.GenericWebApplicationContext
中声明的方法应用
@Advice.OnMethodEnter
。为此,我编写了一个最小代理:

公共类SequenceAgent{
public static void premain(最终字符串参数,
最终仪表(仪表){
新建AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.type(名称开始与否)(
“org.springframework.web.context.support.GenericWebApplicationContext”))
.transform((生成器、类型描述、类加载器、模块)->builder
.method(any()).intercept(Advice.to(SequenceAdvice.class)))
.installOn(仪器仪表);
}
公共静态类序列通知{
@忠告,忠告
静态无效输入(@Advice.This Object thiz,@Advice.Origin Method,
@Advice.AllArguments对象…args){
字符串className=thiz.getClass().getName();
String methodName=method.getName();
System.out.println(“输入:”+className+“#”+methodName);
}
}
}
我希望此配置会过滤掉
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
,因为它与
org.springframework.web.context.support.GenericWebApplicationContext
不匹配,但看起来也会拦截对此类对象的方法调用:

import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
公共类代理测试{
公共静态void main(字符串[]args){
注释ConfigServletWebServerApplicationContext上下文=
新注释ConfigServletWebServerApplicationContext();
containsBean(“SomeBean”);
}
}
连接到代理并运行时,它会打印出来(为可读性而包装):

org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServe.ApplicationContext
的类层次结构是:

org.springframework.core.io.DefaultResourceLoader
        ⇧
org.springframework.context.support.AbstractApplicationContext
        ⇧
org.springframework.context.support.GenericApplicationContext
        ⇧
⤏⤏⤏⤏ org.springframework.web.context.support.GenericWebApplicationContext
        ⇧
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext
        ⇧
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServe.ApplicationContext
并且
containsBean
方法在以下内容中声明和重写:

org.springframework.beans.factory.BeanFactory#containsBean
        ⇧
org.springframework.context.support.AbstractApplicationContext#containsBean

为什么
包含bean
@Advice.thiz
这个对象解析为
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
,而不是
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

Byte Buddy使用String.startsWith

您看到的是字节伙伴检测类,而不是实例。在某种程度上,可以考虑将通知代码复制到目标方法中


因此,所有子类都将受到影响。为了完成您正在做的事情,您需要在调用期间检查实例类的类型,就像您希望在Java中实现这一点一样

您的意思是当检测到
GenericWebApplicationContext
类时,其超类中声明的所有方法也会检测到吗?因为
包含bean(…)
不是在
GenericWebApplicationContext
中声明的,而是在其
AbstractApplicationContext
超类中声明的。所有继承的方法都是。Byte Buddy会像在源代码中一样更改类。但是IIRC,
GenericWebApplicationContext.java
的源代码中没有
containsBean
,而是在它的一个超类中定义的。您可以通过将Thread.dump()添加到tge通知中来轻松验证这一点。
org.springframework.beans.factory.BeanFactory#containsBean
        ⇧
org.springframework.context.support.AbstractApplicationContext#containsBean