如何在构造函数拦截器中启动对象字段?
我在Buddy代码中创建了一个字节构造函数。
Class<?> klass = new ByteBuddy()
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.defineProperty("origin", CoreObject.class, true)
.defineProperty("variableNamedField", Map.class, true)
.defineConstructor(Visibility.PUBLIC)
.withParameters(CoreObject.class)
.intercept(
// Invoke Objects default constructor explicitly
MethodCall.invoke(Object.class.getConstructor())
.andThen(FieldAccessor.ofField("origin").setsArgumentAt(0))
.andThen(FieldAccessor.ofField("variableNamedField").setsValue(new HashMap<>()))
.andThen(MethodDelegation.to(new FillMapInterceptor("variableNamedField")))
//
// I have to fill the map.
// Something like this:
//
// variableNamedField.put("first", new FirstHandler(origin));
// variableNamedField.put("second", new SecondHandler(origin));
//
)
.make()
.load(CoreObject.class.getClassLoader())
.getLoaded();
构造函数首先将参数保存到私有字段。然后它创建集合。然后它调用以下拦截器来填充该集合。
class FillMapInterceptor {
private final String mapField;
public FillMapInterceptor(String mapField) {
this.mapField = mapField;
}
public void construct(@FieldValue("variableNamedField") Map<String, Handler> map, @FieldValue("origin") CoreObject coreObject){
map.put("first", new FirstHandler(coreObject));
map.put("second", new SecondHandler(coreObject));
}
}
最好在拦截器中实例化variableNamedField字段,因为事实证明,每次创建新的类实例时,variableNamedField字段都是用相同的HashMap对象实例化的。但是,我只能通过@FieldValue注释将现有字段传递给拦截器。但我似乎无法在拦截器中为字段分配新变量。
最简单的方法是使用Advice
类定义构造函数。advice类允许您使用稍后内联的模板定义代码。你可以使用@Advice。OnMethodExit
在本例中,在上述实现之后添加代码,然后环绕上面已经创建的代码:
Advice.to(YourAdvice.class).wrap(...)
您可以在javadoc中找到有关定义建议的所有信息,基本上,您可以将上面的代码复制粘贴到一个静态方法中以内联它:
class YourAdvice {
@Advice.OnMethodExit
static void exit(@Advice.FieldValue("variableNamedField")
Map<Object, Object> variableNamedField) {
variableNamedField.put("first", new FirstHandler(origin));
variableNamedField.put("second", new SecondHandler(origin));
}
}
我正在尝试用Byte Buddy拦截构造函数调用,这是我的示例代码: 我看到了这个相关的问题,但是,我得到了一个冲突异常(就好像构造函数被定义了两次)。
我必须将注释XmlElementWrapper和XmlElement添加到列表类型的字段,但是这些注释需要名称。我想把属性名设置为字段名。我愿意: 这是我的拦截器: 这是目标类的一部分: 但我有一个例外: [public static void factory.framework.SetterListInterceptor.getter(java.lang.reflect.Method)、publ
我试图通过java应用程序中的所有外部调用传递监视/跟踪信息。为了使其透明,我尝试使用byte-buddy,但在使其工作时遇到了一些困难。 为了跟踪每个传入的(http)请求,我截获了HttpServlet。service(),从HttpServletRequest中提取令牌头,并将其放在名为TokenHolder的类中的静态ThreadLocal中。 为了跟踪每个传出(超文本传输协议)请求,我拦
问题内容: 如果未将ArrayList初始化为字段,则将项目添加到ArrayList时出现NullPointerException。谁能解释为什么? 当我将ArrayList初始化为字段时起作用: 当我将ArrayList声明为字段然后在Class构造函数中对其进行初始化时,它不起作用: 问题答案: 因为构造函数中的版本正在创建一个新变量,而该变量恰好与您的成员字段名称相同,而成员字段仍未设置。这
我在使用Byte Buddy时遇到了一个简单的问题,下面是我的代码: 我希望工作并将调用转发到受人尊敬的拦截器实例,但是我得到这个异常: 最奇怪的部分在异常消息的最后: 我做错了什么?
这是一个关于java中子类的非常基本的问题,我还是不明白…… 假设我有一个超类,它有三个字段,并且只有默认的构造函数: 我想添加一个字段x。我无法更改,所以我创建了一个子类: 我现在想从现有的对象生成object: 这样我仍然可以访问,等。 如果不在子类的构造函数中“手动”分配所有这些字段,我如何才能最好地做到这一点?