Сервисы ServerContext
Сервис — интерфейс, наследующий маркер ru.bgcrm.context.core.service.Service и зарегистрированный в ServiceFactory. Сервисы являются публичной точкой бизнес-операций для action, listener, task, динамического кода и других компонентов ERP.
Жизненный цикл
ServerContext хранит пользователя, режим транзакции, соединения, repositories и созданные сервисы. Первый запрос интерфейса создаёт реализацию и proxy; последующие запросы того же интерфейса в этом контексте возвращают тот же экземпляр proxy.
Proxy выполняет инфраструктурные обработчики вызова и после успешного вызова подтверждает и освобождает соединения в нетранзакционном режиме. Поэтому реализацию сервиса не следует создавать вручную в прикладном коде.
| Режим контекста | Поведение |
|---|---|
|
Все сервисы разделяют соединения контекста. Изменения подтверждаются явным |
|
После сервисного вызова соединения освобождаются автоматически; режим подходит для независимых операций чтения и коротких записей |
После закрытия контекста полученный сервис использовать нельзя.
Получение сервиса
Kotlin
import ru.bgcrm.context.core.ServerContext
import ru.bgcrm.context.core.getService
import ru.bgcrm.model.param.service.ParameterService
val parameterService = ServerContext.get().getService<ParameterService>()
Java
ParameterService parameterService =
ServerContext.lookup(ParameterService.class);
Если объект ServerContext уже передан явно:
ParameterService parameterService =
context.getService(ParameterService.class);
Передавайте сервис в конструктор компонента, если это упрощает тестирование. Значением по умолчанию может быть lookup текущего контекста, но бизнес-метод не должен многократно искать один сервис.
Создание отдельного контекста
HTTP-запросы и штатные обработчики уже выполняются в контексте. Для команды или интеграционного callback без контекста используйте withContext/runWithContext:
withContext(user, transactional = true) {
getService<ProcessService>().addDescription(processId, message)
}
withContext подтверждает транзакцию после успешного завершения блока и всегда закрывает контекст. Не прикрепляйте один ServerContext одновременно к нескольким потокам. Полный жизненный цикл описан на странице GlobalContext и ServerContext, режимы соединений — на странице Соединения и транзакции.
Основные доменные сервисы
| Интерфейс | Пакет | Назначение |
|---|---|---|
|
Процессы, статусы, группы, исполнители и привязки |
|
|
Значения параметров с проверками и событиями |
|
|
|
Те же операции с параметрами без событий изменения |
|
|
Чтение типа и сериализованного значения, когда внешний клиент заранее не знает тип параметра; поддержка типов неполная |
|
|
Операции с контрагентами |
|
|
Поиск и получение пользователей |
|
|
Справочник типов работ |
|
|
Копирование наборов параметров между объектами |
|
|
Связи узлов/объектов контекста |
ProcessService также разделён на узкие сервисы: CommonProcessService, ProcessCreatorService, ProcessGroupsService, ProcessExecutorsService, LinkService, ProcessLinkService, LinkedCustomerService, LinkedContractService, LinkedCommonContractService и CommonLinkService. Запрашивайте узкий интерфейс, если компоненту не нужен весь фасад.
Задачи и планировщик
| Интерфейс | Назначение |
|---|---|
Определения задач: создание, изменение, поиск и удаление |
|
Планирование и состояние запусков задачи для процесса |
|
|
Исполнение готового запуска задачи |
|
Определения задач планировщика |
|
История и состояние запусков планировщика |
Модуль Task и планировщик решают разные задачи: первый создаёт отложенную работу для процесса, второй запускает периодические служебные задачи.
Инфраструктурные сервисы
| Интерфейс | Назначение |
|---|---|
|
Создание HTTP-клиентов Retrofit |
|
Провайдеры авторизации HTTP-клиентов |
|
Хранение токенов интеграций |
|
Каталог контекстных переменных |
|
Построение значений контекстных переменных |
|
Обработка текстовых шаблонов с контекстными переменными |
|
Метаданные файлов |
|
Временные файлы |
|
Асинхронное файловое хранилище |
|
Журналы изменений сущностей |
|
История версий ERP |
Плагины регистрируют дополнительные сервисы. Актуальный полный список статических привязок находится в ru.bgcrm.context.core.ServiceModule и DI-модулях плагинов. Правила регистрации и кэширования приведены в разделе DI: RepositoryModule и ServiceModule.
Когда нужен repository
Repository является внутренним слоем хранения. Вызывающий код должен предпочитать сервис, если соответствующая операция существует: сервис добавляет проверки, события, telemetry и согласованную транзакцию.
Прямой repository оправдан внутри реализации сервиса или для новой операции, для которой сервисный контракт ещё проектируется. SQL размещается только в DAO/repository-пакетах.
Добавление сервиса
-
Создайте интерфейс с узким контрактом и унаследуйте
Service. -
Реализацию разместите в
implлибо оформите фасадом принятого в модуле типа. -
Передавайте repositories и другие зависимости через конструктор.
-
Зарегистрируйте интерфейс в
ServiceModuleядра или DI-модуле плагина. -
Добавьте unit-тесты реализации и сценарий получения через
ServerContextпри изменении DI. -
Задокументируйте назначение, транзакционные границы, события, ошибки и нетривиальные побочные эффекты.
Не регистрируйте реализацию вместо интерфейса и не сохраняйте сервис в глобальном singleton: его жизненный цикл ограничен ServerContext.