Шаблон Observer и SpringBoot @Service

Может ли кто-нибудь помочь мне, как обращаться с шаблоном наблюдателя и SpringBoot @Service?

Представим, что у меня есть класс:

WeatherStation[temperature, humidity, windSpeed ...] - subject (observable)

У меня может быть много этих классов, и мне нужно обновлять данные в базе данных, поэтому при изменении температуры мне нужно регистрировать их в базе данных под правильной WeatherStation.

Я пришел с тремя решениями, первое:

Создайте класс WeatherStationObserver, который будет иметь ссылку на WeatherStationRepository, и я зарегистрирую один WeatherStationObserver для одного WeatherStation, и WeatherStationObserver сохранит данные в базе данных (это похоже на то, как я это реализовал прямо сейчас), но есть некоторые недостатки. Например я не могу @Autowire to WeatherStationObserver и не могу сделать методы @Transactional...

Вторая идея:

Создайте WeatherStationUpdateService, который будет вызываться из WeatherStationObserver. Мне это не нравится, потому что WeatherStationObserver служит здесь только для вызова WeatherStationUpdateService.

Третья идея:

Сделайте службу наблюдателем и зарегистрируйте ее для каждой WeatherStation, но я не уверен, что служба не должна вызываться только извне и является ли хорошей практикой, чтобы служба действовала как наблюдатель.

Может ли кто-нибудь помочь мне здесь?

Почему у вас "много этих классов"? Как данные с этих метеостанций попадают на ваш сервер? Получаете ли вы данные, отправляемые с одной станции за раз ... или есть какой-то шлюз, который означает, что вы получаете, скажем, 300 значений метеостанций в одном HTTP-запросе для обработки?

Jcov 11.12.2020 14:47

Привет, спасибо за вопрос, я общаюсь с WeatherStations независимо через OPC UA. Таким образом, один класс WeatherStation представляет одну физическую метеостанцию, поэтому данные обновляются независимо от других.

Jakub Znamenáček 11.12.2020 15:18

У меня может быть идея. Я предполагаю, что у каждого есть идентификатор, на который вы ссылаетесь?

Jcov 11.12.2020 15:22

Да и нет, класс WeatherStation не имеет ссылки на идентификатор, но у него есть IP-адрес, который должен быть уникальным, чтобы он мог служить идентификатором для поиска в БД.

Jakub Znamenáček 11.12.2020 15:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
615
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сохраните метеостанции в базе данных с соответствующими идентификаторами.

Рядом с каждым есть время «последнего опроса».

Создайте задачу @Scheduled and @Transactional, которая извлекает страницу, скажем, из 20 станций, которые не были опрошены в последнее время (в течение x секунд), и запрашивает у них их данные, обрабатывает их и постоянно обновляет «последний опрос» для каждой.

Если вы ДОЛЖНЫ иметь их все как можно ближе друг к другу, тогда выполните выборку данных OPC UA, и когда каждый из них возвращается, просто поместите данные в очередь (например, ActiveMQ), а затем получите @JmsListener, который будет обрабатывать эту очередь, извлекая ее в время выполнения сохранения (чтобы не сильно ударить по базе данных).

Я не уверен, что понимаю это решение. Мой вопрос был в значительной степени в том, может ли служба быть НАБЛЮДАТЕЛЕМ класса WeatherStation. Вы можете проверить класс PlcAutomaticUpdateServiceImpl здесь. Метеостанция была просто упрощенным примером.

Jakub Znamenáček 11.12.2020 15:39

Ах, извините, вы имеете в виду, что если поле в одной из «WeatherStation» изменяется, то вызываются определенные @services?

Jcov 11.12.2020 15:47

Да, точно! :)

Jakub Znamenáček 11.12.2020 15:48

Может быть, это то, что вы можете использовать? baeldung.com/spring-events

Jcov 11.12.2020 15:48

У меня есть рабочее решение, я просто не уверен, что это лучший способ (правильный), как это сделать. В примере с WeatherStation это будет выглядеть так, что мне нужно сделать WeatherStation.register(weateherStationService). Затем WeatherStationService включает метод onChange(WeatherStation WeatherStation), и в этом методе я обновляю репозиторий.

Jakub Znamenáček 11.12.2020 15:57

Другие вопросы по теме