Доступ к полям из прокси-объекта - PullRequest
9 голосов
/ 14 марта 2012

Я столкнулся с интересной проблемой при разработке платформы ORM для Android. Я использую библиотеку dexmaker для манипулирования байт-кодом, которая позволяет мне создавать прокси для постоянных объектов для реализации отложенной загрузки.

Экземпляр прокси имеет связанный InvocationHandler, так что когда метод вызывается на прокси, метод invoke вызывается на InvocationHandler, который затем вызывает соответствующий метод объекта прокси, предполагая, что он загружен лениво. Ничего удивительного - это все равно, что класс Java Proxy , но он позволяет мне проксировать реальные классы вместо интерфейсов (см. ProxyBuilder от dexmaker.)

Часть, которая стала проблематичной, заключается в том, что я также использую отражение для извлечения значений полей из постоянных объектов и - теперь, когда я ввел ленивую загрузку - прокси. Вот что я сейчас делаю:

for (Field f : getPersistentFields(model.getClass()) {
    ...
    Object val = f.get(model); // model is either a persistent object or a proxy for one
    mapField(f, val, map);
}

Это, конечно, работает для обычных экземпляров модели, но для проксируемых экземпляров f.get(model) не получает значение поля объекта прокси. Вместо этого он возвращает значение по умолчанию, назначенное в конструкторе класса. Доступ к полю прокси явно не перехватывается.

У меня такой вопрос: Можно ли как-то перехватить доступ к переменной-члену прокси, созданной с помощью отражения? Если нет, то как я могу получить значение поля прокси «отраженным» способом?

Один из возможных обходных путей Я думаю о том, чтобы получить и затем вызвать метод получения поля с использованием отражения, но мне интересно, есть ли более прямое решение. Этот обходной путь, если он действительно работает , потребовал бы, чтобы у объекта был метод getter для всех постоянных полей - требование, которое обычно должно соблюдаться с точки зрения ОО-проектирования, но также заставляет больше работать на пользователь фреймворка.

Я открыт для любых идей.

1 Ответ

1 голос
/ 17 мая 2012

Хорошим решением является доступ к полям с помощью метода установки / получения, а не с использованием класса поля.(Я считаю, что это больше, чем обходной путь)

С другой стороны, если вы хотите использовать подход прямого доступа к полю.Насколько я вижу, нет простого способа перехватить доступ к полю.Пожалуйста, проверьте ответы на этот вопрос .Хотя вопрос связан с перехватом модификации поля, а не с чтением поля, оно может дать некоторую информацию и направление.

...