Можно ли отключить функциональную привязку spring-cloud-stream для определенного метода?

У меня есть библиотека на основе Spring Boot (с использованием spring-data-mongo), которая создает PersistentEntities bean. PersistentEntities реализует интерфейс Supplier<T>, поэтому функциональный связыватель Spring Cloud Stream создает привязку к нему. В частности, BeanFactoryAwareFunctionRegistry.discoverDefaultDefinitionIfNecessary находит его как bean-компонент типа Supplier.

Мы используем связыватель Spring Cloud Streams Kafka, поэтому Spring пытается опубликовать каждый из этих объектов в создаваемой им теме Kafka. Это вызывает проблему с бесконечной рекурсией в сериализаторе JSON:

2019-12-04 15: 36: 54.323 ОШИБКА 1 --- [scheduling-1] o.s.i.h.LoggingHandler: org.springframework.messaging.MessagingException: не удалось вызвать метод; вложенное исключение - org.springframework.messaging.converter.MessageConversionException: не удалось записать JSON: бесконечная рекурсия (StackOverflowError) (через цепочку ссылок: org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity ["idProperty"]. springframework.data.mongodb.core.mapping.CachingMongoPersistentProperty ["владелец"] -> org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity ["idProperty"] -> org.springframework.data.mongodb.core.mapping. CachingMongoPersistentProperty ["владелец"] -> org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity ["idProperty"] -> org.springframework.data.mongodb.core.mapping.CachingMongoPersistentProperty> ["владелец". springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity ["idProperty"] -> org.springframework.data.mongodb.core.mapping.CachingMongoPersistentProperty ["владелец"] -> org.springframework.data.mongodb.core.mapping. BasicMongoPersistentEntity ["idProperty"] -> org.springframewor k.data.mongodb.core.mapping.CachingMongoPersistentProperty ["владелец"] -> org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity ["idProperty"] -> org.springframework.data.mongodb.core.mapping. CachingMongoPersistentProperty ["владелец"] ...

Есть ли способ исключить мой bean-компонент из привязки функций? Проект, использующий эту библиотеку, не использует функцию Spring Cloud, но я бы предпочел оставить эту возможность открытой.

Для справки, мой bean-компонент определяется как:

@Bean
public PersistentEntities myPersistentEntities(List<MongoTemplate> mongoTemplates) {
    return new PersistentEntities(() -> {
        List<MappingContext<?, ?>> mappingContexts = mongoTemplates.stream().map(t -> t.getConverter().getMappingContext()).collect(Collectors.toList());
        return mappingContexts.iterator();
    });
}

Мы только что обновили Spring Cloud с Greenwich до Hoxton, поэтому автоматические функциональные привязки для нас в новинку.


person Brian    schedule 04.12.2019    source источник


Ответы (2)


Как правило, вы можете исключить функцию spring -cloud, явно исключив ее как

@SpringBootApplication(exclude = ContextFunctionCatalogAutoConfiguration.class)

Тем не менее, поднимите вопрос - https://github.com/spring-cloud/spring-cloud-stream/issues. Варианты этого возникали раньше, и я начинаю полагать, что нам нужно лучшее решение, чем описано выше.

Другой обходной путь - явно указать свойство spring.cloud.function.definition=blah, где blah - это то, чего не существует. Уродливо, но помогает и не требует перекомпиляции, так как не используются аннотации или дополнительные атрибуты.

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

person Oleg Zhurakousky    schedule 04.12.2019
comment
В итоге я обманул и создал bean-компонент FunctionCatalog, который имел тот же эффект, но более явный. Я также создал новую проблему: github.com/spring-cloud / spring-cloud-stream / issues / 1865 - person Brian; 05.12.2019

Итак, я столкнулся с чем-то похожим. TL; исправление DR заключалось в явном определении функций, доступных для Spring Cloud Streams, например:

Имя Consumer Bean: inputConsumer

spring:
  cloud:
    stream:
      function:
        bindings:
          inputConsumer-in-0: DataInputBinding
        definition: inputConsumer
      bindings:
        DataInputBinding:
          binder: kinesis
          destination: whatever
          group: whatever

В моей ситуации в моем приложении была еще одна пружина Component, которая реализует Supplier. Без явного определения функций в конфигурации Spring Cloud Streams просто добавляет все компоненты Function, Consumer и Supplier в FunctionCatalog, а затем ожидает, что все они будут присоединены к потоку.

Видимо, если их нет, то он их просто не подключает и ничего не работает. : /

person Scott    schedule 01.04.2021