我让Byte Buddy作为代理运行并且它成功地拦截了我的绝大部分代码库,顺便说一下这个代码库非常大!虽然有一些异常值我无法检测,但我已在下面记录,希望你能知道答案!
1。 CGLIB生成了类
Spring会生成一些与我的类名相同但附加"$$EnhancerByCGLIB$$"
的类,这些类会导致错误。
我得到的错误是:
java.lang.IllegalStateException: Cannot resolve type description for com.mycompany.MySpringBean$$EnhancerByCGLIB$$ee9d3c37_2
at net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:152)
at net.bytebuddy.pool.TypePool$LazyFacade$LazyResolution$LazyTypeDescription.resolve(TypePool.java:3158)
at net.bytebuddy.pool.TypePool$LazyFacade$LazyResolution$LazyTypeDescription.getModifiers(TypePool.java:3238)
at net.bytebuddy.ByteBuddy.rebase(ByteBuddy.java:697)
事实上,我没有兴趣检测CGLIB生成的类,因此希望将它们排除在外。什么是最好的方法?目前,我按名称进行匹配,但我想知道这是否是最佳方式。
.and(not(nameContains("EnhancerByCGLIB")))
2。包私人和私人课程
我看到的另一个问题是检验package private
或private class
。
Package private
代码如下所示:
abstract class BaseBean {
Object methodA(final String customerNumber){}
}
我得到的错误是:
Caused by: java.lang.IllegalAccessException:
Class net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField cannot
access a member of class com.mycompany.BaseBean with modifiers "public static"
Private class
代码如下所示:
public class Object A {
//variables & methods...
private class ObjectB {}
}
我得到的错误是:
Caused by: java.lang.IllegalAccessException:
Class net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField cannot
access a member of class com.mycompany.ObjectA$ObjectB with modifiers "public static"
Byte Buddy乐器package private
或private classes
?
第3。沉默失败
这只是一个普遍的问题,但有可能指示Byte Buddy在每个课堂上默默地失败吗?这是因为任何这样的错误都不会阻止应用程序启动或者Byte Buddy尽可能多地进行检测。
4。公共抽象类中的公共方法
我的代码类似于:
package com.mycompany;
public interface InterfaceA{
Object provideAccess(final String id);
}
package com.mycompany;
public abstract class BaseBeanA implements InterfaceA {
//some general helper methods
}
package com.mycompany;
public abstract class BaseBeanB extends BaseBeanA {
//some specific helper methods
}
package com.mycompany;
public class BeanImpl extends BaseBeanB {
protected Object provideAccess(final String id) {
}
}
这会导致在检测BaseBeanB时出现以下错误:
java.lang.IllegalArgumentException:[protected void java.lang.Object.finalize()抛出java.lang.Throwable,public final native void java.lang.Object.wait(long)throws java.lang.InterruptedException,public final void java.lang.Object.wait()抛出java.lang.InterruptedException,public final void java.lang.Object.wait(long,int)throws java.lang.InterruptedException,public boolean java.lang.Object.equals(java.lang.Object),public java.lang.String java.lang.Object.toString(),public native int java.lang.Object.hashCode(),public final native java.lang.Class java.lang.Object.getClass(),受保护的本机java.lang.Object java.lang.Object.clone()抛出java.lang.CloneNotSupportedException, public final native void java.lang.Object.notify(),public final native void java.lang.Object.notifyAll(),public java.lang.Object com.mycompany.MyInterceptor.intercept(java.util.concurrent.Callable,java.lang.Object中[],java.lang.reflect.Method中,java.lang.Class中) throws java.lang.Exception]允许从公共抽象派生 对象com.mycompany.InterfaceA.provideAccess(java.lang.String)
答案 0 :(得分:5)
<强> 1。 CGLIB生成了类
您的解决方案是正确的。事实上,通过名称指定类对性能总是有好处的。例如,如果您可以排除整个包,Byte Buddy可能已经丢弃了一个类,甚至没有解析类文件,因为名称可以单独使用。
cglib生成的类的检测失败的原因是这些类没有可用的字节代码。
<强> 2。包私人和私人课程
你在这里发现了一个错误。我最近重构了这个逻辑,通过将它们公开来不要求合成字段的可访问性,但我只是忘记了包私有字段。这在主分支上修复,将在0.7-rc7中发布。
第3。沉默失败
如果检测失败,则始终向AgentBuilder.Listener
报告此失败。除此之外,失败没有效果,因为ClassFileTransformer
API暗示了这一点。你观察到通过的任何例外吗?您可能还想查看侦听器AgentBuilder
被重构的最新版本。
<强> 4。公共抽象类中的公共方法
您的拦截器定义了Callable
类型的参数,我假设该参数由SuperCall
注释。这会注入一个代理来调用截获方法的super方法(如果存在)。对于像你试图拦截的抽象方法,这不起作用,Byte Buddy决定你的拦截器不可绑定。因此,抛出异常。
这样说,通过从委托中排除Object类型的方法,Byte Buddy不会将它们视为委托。这样可以提高性能。