Spring Boot 2.x с Ehcache 3.x - служба @Autowired имеет значение null внутри пользовательского CacheEventListener

Я использую Ehcache в качестве буфера для передачи данных для всех клиентов, подключенных к WebSocket (Spring).

Реализация CacheEventListener:

public class CacheListener implements CacheEventListener<ArrayList, MeasurementPoint> {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate; //<-- This is null at runtime

    @Override
    public void onEvent(CacheEvent<? extends ArrayList, ? extends MeasurementPoint> cacheEvent) {
        simpMessagingTemplate.convertAndSend("/topic/measurementsPoints", cacheEvent.getNewValue());
    }
}

XML-файл конфигурации Ehcache:

config
        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns='http://www.ehcache.org/v3'
        xsi:schemaLocation = "
            http://www.ehcache.org/v3
            http://www.ehcache.org/schema/ehcache-core-3.7.xsd">
    <!-- Default cache template -->
    <cache-template name = "default">
        <resources>
            <heap>1000</heap>
            <offheap unit = "MB">10</offheap>
        </resources>
    </cache-template>

    <cache alias = "measurementsCache" uses-template = "default">
        <key-type>java.util.ArrayList</key-type>
        <value-type>br.com.petrobras.risersupervisory.model.MeasurementPoint</value-type>
        <listeners>
            <listener>
                <class>br.com.petrobras.risersupervisory.framework.CacheListener</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>UPDATED</events-to-fire-on>
            </listener>
        </listeners>
    </cache>
</config>

Я пытался следовать некоторым руководствам, но все они используют библиотеку журналов или System.out.println внутри реализации CacheEventListener.

Есть ли способ, которым я могу автоматически подключить @Service(Spring) внутри CacheEventListener? Является ли эта реализация неправильной? Я не смог найти ни одного примера использования @Autowired внутри CacheEventListener.

Obs: не только SimpMessagingTemplate имеет значение null во время выполнения. Я тоже пробовал автосвязывать пользовательский класс, и результат был таким же.

Obs2: после поиска журналов весенней загрузки я считаю, что CacheEventListener был привязан к кешу до завершения загрузки весенней загрузки. Не уверен, что это проблема.

Можете ли вы попытаться аннотировать свой CacheListener с помощью аннотации @Component? это позволило бы внедрять зависимости с помощью Autowired

Benjamin Caure 15.12.2020 23:53

@BenjaminCaure Я добавил @Component в класс CacheListener (тот, который реализует CacheEventListener), но, к сожалению, simpMessagingTemplate по-прежнему равен нулю.

Thiago Carvalho 16.12.2020 00:08

CacheListener не контролируется Spring и поэтому не будет внедрен.

M. Deinum 16.12.2020 08:05

Спасибо за разъяснение @M.Deinum, я этого не знал. Я следовал руководству, указанному Hopey One, и это решило проблему.

Thiago Carvalho 17.12.2020 08:44

Любая дополнительная информация, потому что у меня такая же проблема.

Zorglube 04.11.2022 15:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
512
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Obs2: после поиска журналов весенней загрузки я считаю, что CacheEventListener был привязан к кешу до завершения загрузки весенней загрузки. Не уверен, что это проблема.

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

@Component
public class SpringContext implements ApplicationContextAware {
 
private static ApplicationContext context;
 
  public static <T extends Object> T getBean(Class<T> beanClass) {
    return context.getBean(beanClass);
  }
 
  @Override
  public void setApplicationContext(ApplicationContext context) throws BeansException 
  {
     
    // store ApplicationContext reference to access required beans later on
    SpringContext.context = context;
  }
}

SpringContext.getBean(YourBean.class);

У вас все еще может возникнуть проблема, если вы попытаетесь сделать это до инициализации контекста spring. Стоит отметить, что spring-bootподдерживает ehcache 3.x через зависимость org.springframework.boot:spring-boot-starter-cache. Я не знаю, подходит ли это для вашей цели, но может быть проще, если ehcache интегрирован с Spring.

Это было именно то, что мне было нужно! Спасибо за помощь, @Hopey One!

Thiago Carvalho 17.12.2020 08:46

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