Как я могу инициировать поля объекта в конструкторе-перехватчике?
Я создал конструктор с помощью Byte 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.Но кажется, что я не могу присвоить поле с новой переменной в перехватчике.
- Как инициировать поля класса в конструкторе перехватчика?Я могу только пропустить существующее значение поля с @FieldValue в перехватчике.
- Как сделать имя поля произвольным?Аннотации типа @FieldValue требуют постоянных параметров (например, имен полей).Может быть, я могу каким-то образом взять поле из результата метода defineProperty и передать его перехватчику или использовать в качестве поля перехватчика?
- Как передать параметры конструктора непосредственно в перехватчик?Мне не нравится, как сначала инициировать поле, а затем передать поле перехватчику с помощью аннотации @FieldValue.