Я пытаюсь сделать OGM для перевода объекта в Vertex для OrientDB. В настоящее время я использую GCLib, но я читал, что ByteBuddy может реализовать две важные вещи, которые, если они будут работать, увеличат скорость OGM.
Может ли ByteBuddy реализовать контроль доступа к полям? Я прочитал документ, но он не ясен или я его не понимаю.
Динамически добавить пустой конструктор по умолчанию.
Текущая проблема заключается в следующем: мы не знаем определение класса, которое будет передано в качестве параметра. Идея состоит в том, чтобы переопределить класс и реализовать пустой конструктор, если его нет, добавить поле с именем __BB__Dirty, чтобы установить объект как грязный, если была обнаружена операция назначения, и заставить реализацию интерфейса общаться с объектом.
Пример: общий класс:
public class Example {
int i = 0;
String stringField;
public Example(Strinf s) {
stringField = s;
}
public void addToI(){
i++;
}
}
Теперь у нас есть такой интерфейс:
public interface DirtyCheck {
public boolean isDirty();
}
Итак, я хочу заставить класс Example реализовать интерфейс, метод isDirty(), поле для работы и конструктор по умолчанию, поэтому класс должен быть переведен в:
public class Example implements DirtyCheck {
int i = 0;
String stringField;
boolean __BB__dirty = false;
public Example() {
}
public Example(Strinf s) {
stringField = s;
}
public void addToI(){
i++;
}
public boolean isDirty() {
return this.__BB__dirty;
}
}
и какой-то волшебный присваиватель, поэтому, если какое-либо поле (кроме __BB__dirty) изменяется, для поля __BB__dirty устанавливается значение True;
Я пробовал первую часть этого, но у меня не получилось :(
...
ByteBuddyAgent.install();
Example ex = new ByteBuddy()
.redefine(Example.class)
.defineField("__BB__Dirty", boolean.class, Visibility.PUBLIC)
.make()
.load(Example.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent())
.getLoaded().newInstance();
....
ex.addToI(); // <--- this should set __BB__dirty to true since it
// assign a value to i.
Но я получаю эту ошибку:
Exception in thread "main" java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$1.apply(ClassReloadingStrategy.java:297)
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.load(ClassReloadingStrategy.java:173)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4350)
at Test.TestBB.<init>(TestBB.java:33)
at Test.TestBB.main(TestBB.java:23)
Застрял на самом первом этапе решения проблемы с ББ. Спасибо