ОБНОВЛЕНИЕ : перехватчик действительно вызывается.Однако, если я устанавливаю точку останова в методе перехвата, точка останова не срабатывает (хотя метод действительно вызывается).Если я устанавливаю точку останова в методе, вызываемом из перехватчика, то он срабатывает (потому что точка останова не была вызвана в первом случае, это заставило меня думать, что перехватчик не был вызван)
Iя пытаюсь использовать ByteBuddy для реализации прокси-класса для отслеживания всех изменений на сущности следующим образом:
public class EntityProxyGenerator{
public static <T extends Entity> T createProxy(T entity) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException {
EntityChangesInterceptor interceptor = new EntityChangesInterceptor(entity);
_class = entity.getClass();
Class Proxy =
new ByteBuddy()
.subclass(_class)
.method(ElementMatchers.isSetter())
.intercept(MethodDelegation.to(interceptor))
.make()
.load(EntityProxyGenerator.class.getClassLoader())
.getLoaded();
return (T) Proxy.getDeclaredConstructor().newInstance();
}
}
и EntityChangesInterceptor
реализовано следующим образом:
public class EntityChangesInterceptor<T extends Entity> {
private final T original;
public EntityChangesInterceptor(T original) {
this.original = original;
}
public boolean isValueObject(Object object) {
Class<?> class_ = object.getClass();
if (class_ == String.class
|| class_ == Integer.class
|| class_ == Double.class
|| class_ == Timestamp.class
|| class_ == Instant.class) {
return true;
}
return false;
}
boolean isPropertyGetter(Method method, Object[] args) {
return method.getName().startsWith("get") && args.length == 0;
}
boolean isPropertySetter(Method method, Object[] args) {
return method.getName().startsWith("set") && args.length == 1;
}
@RuntimeType
public Object intercept(@Origin Method method, @AllArguments Object[] args) throws Throwable {
try {
if (isPropertySetter(method, args)) {
if (isValueObject(args[0])) {
String propertyName = method.getName().substring(3);
String getter = "get" + propertyName;
Object oldValue = MethodUtils.invokeMethod(original, getter, null);
Object newValue = args[0];
ValueChange valueChange = new ValueChange(propertyName, oldValue, newValue);
Object callResult = method.invoke(original, args);
original.addPropertyChange(valueChange);
return callResult;
}
}
return method.invoke(original, args);
} finally {
// do your completion logic here
}
}
}
Прокси создан правильно, однако всякий раз, когда я пытаюсь вызвать сеттер для прокси-класса, EntityChangesInterceptor.intercept
никогда не вызывается.
Если я изменю реализацию прокси-класса так, чтобы он перехватывал получатели следующим образом, то все работаетштраф:
Class Proxy = new ByteBuddy()
.subclass(_class)
.method(ElementMatchers.isGetter()) // note isGetter() instead of isSetter()
.intercept(MethodDelegation.to(interceptor))
.make()
.load(EntityProxyGenerator.class.getClassLoader())
.getLoaded();