Может ли кто-нибудь помочь мне, как обращаться с шаблоном наблюдателя и SpringBoot @Service?
Представим, что у меня есть класс:
WeatherStation[temperature, humidity, windSpeed ...] - subject (observable)
У меня может быть много этих классов, и мне нужно обновлять данные в базе данных, поэтому при изменении температуры мне нужно регистрировать их в базе данных под правильной WeatherStation.
Я пришел с тремя решениями, первое:
Создайте класс WeatherStationObserver, который будет иметь ссылку на WeatherStationRepository, и я зарегистрирую один WeatherStationObserver для одного WeatherStation, и WeatherStationObserver сохранит данные в базе данных (это похоже на то, как я это реализовал прямо сейчас), но есть некоторые недостатки. Например я не могу @Autowire to WeatherStationObserver и не могу сделать методы @Transactional...
Вторая идея:
Создайте WeatherStationUpdateService, который будет вызываться из WeatherStationObserver. Мне это не нравится, потому что WeatherStationObserver служит здесь только для вызова WeatherStationUpdateService.
Третья идея:
Сделайте службу наблюдателем и зарегистрируйте ее для каждой WeatherStation, но я не уверен, что служба не должна вызываться только извне и является ли хорошей практикой, чтобы служба действовала как наблюдатель.
Может ли кто-нибудь помочь мне здесь?
Привет, спасибо за вопрос, я общаюсь с WeatherStations независимо через OPC UA. Таким образом, один класс WeatherStation представляет одну физическую метеостанцию, поэтому данные обновляются независимо от других.
У меня может быть идея. Я предполагаю, что у каждого есть идентификатор, на который вы ссылаетесь?
Да и нет, класс WeatherStation не имеет ссылки на идентификатор, но у него есть IP-адрес, который должен быть уникальным, чтобы он мог служить идентификатором для поиска в БД.
Сохраните метеостанции в базе данных с соответствующими идентификаторами.
Рядом с каждым есть время «последнего опроса».
Создайте задачу @Scheduled and @Transactional
, которая извлекает страницу, скажем, из 20 станций, которые не были опрошены в последнее время (в течение x секунд), и запрашивает у них их данные, обрабатывает их и постоянно обновляет «последний опрос» для каждой.
Если вы ДОЛЖНЫ иметь их все как можно ближе друг к другу, тогда выполните выборку данных OPC UA, и когда каждый из них возвращается, просто поместите данные в очередь (например, ActiveMQ), а затем получите @JmsListener
, который будет обрабатывать эту очередь, извлекая ее в время выполнения сохранения (чтобы не сильно ударить по базе данных).
Я не уверен, что понимаю это решение. Мой вопрос был в значительной степени в том, может ли служба быть НАБЛЮДАТЕЛЕМ класса WeatherStation. Вы можете проверить класс PlcAutomaticUpdateServiceImpl здесь. Метеостанция была просто упрощенным примером.
Ах, извините, вы имеете в виду, что если поле в одной из «WeatherStation» изменяется, то вызываются определенные @services
?
Да, точно! :)
Может быть, это то, что вы можете использовать? baeldung.com/spring-events
У меня есть рабочее решение, я просто не уверен, что это лучший способ (правильный), как это сделать. В примере с WeatherStation это будет выглядеть так, что мне нужно сделать WeatherStation.register(weateherStationService). Затем WeatherStationService включает метод onChange(WeatherStation WeatherStation), и в этом методе я обновляю репозиторий.
Почему у вас "много этих классов"? Как данные с этих метеостанций попадают на ваш сервер? Получаете ли вы данные, отправляемые с одной станции за раз ... или есть какой-то шлюз, который означает, что вы получаете, скажем, 300 значений метеостанций в одном HTTP-запросе для обработки?