Расширение Interactor
Архитектура вызова
Interactor.create создаёт JDK proxy только для переданного интерфейса. Цепочка вызова выглядит так:
метод интерфейса
-> ValidationProxyHandler
-> CacheProxyHandler
-> InteractionDispatcher
-> InteractionHandler
-> сервисы и DAO через ServerContext
InteractionDispatcher хранит глобальный список фабрик. Для метода он берёт method.declaringClass, находит совместимый корневой интерфейс и выбирает обработчик по присутствующей на методе аннотации. Экземпляр обработчика создаётся конструктором (Int, ServerContext) и кешируется внутри dispatcher по сигнатуре метода.
Добавление обработчика
-
Создайте runtime-аннотацию с
@Target(AnnotationTarget.FUNCTION)и@MustBeDocumented. -
Реализуйте
InteractionHandlerлибоBaseInteractionHandler<A>. Конструктор должен приниматьobjectId: IntиServerContext. -
Явно проверьте все поддерживаемые типы результата, аргументы и префиксы имени; для остальных сигнатур выбрасывайте понятное исключение.
-
Зарегистрируйте пару «аннотация → обработчик» в каждой фабрике сущности, где операция действительно поддерживается.
-
Добавьте unit-тесты для чтения, записи, пустых значений, неподдерживаемой сигнатуры и значимых префиксов.
-
Обновите справочник обработчиков и матрицу сущностей.
Внешний модуль может зарегистрировать обработчик во время инициализации:
InteractionDispatcher.registerHandler<ProcessInteractor>(
BindExternalValue::class.java,
ExternalValueInteractionHandler::class.java
)
Повторная регистрация той же аннотации в фабрике запрещена.
Добавление сущности
-
Создайте корневой интерфейс, наследующий
Interactable. -
Создайте
InteractionDispatcherFactoryсtypeи таблицейmapping. -
Добавьте фабрику в начальный список
InteractionDispatcherили зарегистрируйте черезregisterFactoryпри старте модуля. -
Добавьте базовый интерфейс с безопасными общеупотребительными методами.
-
Покройте маршрутизацию и каждый обработчик unit-тестами.
-
Обновите документацию сущностей и обработчиков.
registerFactory запрещает вторую фабрику для того же корневого типа. registerHandler принимает именно зарегистрированный корневой интерфейс; попытка регистрировать обработчик на его дочерний интерфейс завершается ошибкой.
Тесты
Базовые примеры находятся в core/src/test/java/ru/bgcrm/util/interactor:
-
InteractorDispatcherTest— выбор фабрики и регистрация; -
CacheProxyHandlerTest— кеш и его сброс; -
ValidationProxyHandlerTestи тесты валидаторов — входные и выходные ограничения; -
handler/common/param— сигнатуры параметров; -
handler/processиhandler/tmc— процессные связи, статусы и интеграция TMC.
Для нового поведения недостаточно проверить только успешное чтение. Нужны регрессионные сценарии с null, пустой коллекцией, несколькими связанными объектами, изменением после кеширования и неверной сигнатурой.