Spring, использующий определенные библиотеки bean-компонентов, конфликтует с приложением

У меня есть несколько веб-приложений с весенней загрузкой и одна библиотека интеграции, используемая всеми веб-приложениями. Библиотека интеграции использует Spring для DI и определяет несколько собственных @Bean с назначенными явными именами, в частности ObjectMapper, используемый для выполнения собственной десериализации из вызовов API.

Вот определение bean-компонента ObjectMapper в библиотеке интеграции (в классе @Configuration):

@Bean(name = "Blah.APIObjectMapper")
public ObjectMapper blahAPIObjectMapper() {
    ObjectMapper mapper = new ObjectMapper()
        .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
        .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

    return mapper;
}

В другом месте библиотеки этот ObjectMapper является @Autowired с определенным @Qualifier, например:

@Autowired
@Qualifier("Blah.APIObjectMapper")
private ObjectMapper blahAPIObjectMapper;

Проблема возникает в веб-приложениях. Этот пользовательский компонент ObjectMapper, определенный в библиотеке интеграции, конфликтует с настроенным по умолчанию компонентом ObjectMapper, который я не могу контролировать.

Ошибка:

org.springframework.beans.factory.UnsatisfiedDependencyException: ошибка при создании bean-компонента с именем 'mappingJackson2HttpMessageConverter', определенным в ресурсе пути к классу [org/springframework/boot/autoconfigure/web/JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration.class]: неудовлетворенная зависимость выражается через аргумент конструктора с индексом 0 типа [com.fasterxml.jackson.databind.ObjectMapper]: : не определено квалификационного bean-компонента типа [com.fasterxml.jackson.databind.ObjectMapper]: ожидается один соответствующий bean-компонент, но найдено 2: Мля .APIObjectMapper,_halObjectMapper; вложенным исключением является org.springframework.beans.factory.NoUniqueBeanDefinitionException: Не определен соответствующий bean-компонент типа [com.fasterxml.jackson.databind.ObjectMapper]: ожидается один соответствующий bean-компонент, но найдено 2: Blah.APIObjectMapper,_halObjectMapper


Вопрос. Как предотвратить конфликт Blah.APIObjectMapper библиотеки с ObjectMapper по умолчанию для весенней загрузки, по-видимому, с именем _halObjectMapper?

Я не использую XML-конфигурацию для Spring. Все основано на аннотациях.


person James Dunne    schedule 13.08.2015    source источник


Ответы (3)


_halObjectMapper выглядит как имя компонента, созданного spring-hateoas через @EnableHypermediaSupport.

Spring boot принимает bean-компонент с именем objectMapper, если существует несколько bean-компонентов типа ObjectMapper. Таким образом, вы можете обойти проблему, создав третий bean-компонент сопоставления объектов с именем objectMapper и даже можете использовать один из существующих bean-компонентов ObjectMapper.

@Bean
public ObjectMapper objectMapper(ObjectMapper _halObjectMapper) {
   return _halObjectMapper;
}
person Aestel    schedule 13.08.2015
comment
Не совсем то, что я ищу. Я хотел бы избежать подобных хаков в веб-приложениях. В идеале библиотека интеграции должна быть в состоянии противостоять любым веб-приложениям, которые я интегрирую с минимумом суеты. - person James Dunne; 13.08.2015
comment
Вы должны взглянуть на docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/ - person Aestel; 13.08.2015

Вы можете определить свой bean-компонент ObjectMapper в качестве основного поставщика. Это пример.

@Primary
@Bean(name = "Blah.APIObjectMapper")
public ObjectMapper blahAPIObjectMapper() {

Проблема и решение обсуждались в этой теме.

person Ming L.    schedule 03.02.2017

Я решил это, обменяв библиотеку Hateoas:

До:

<dependency>
  <groupId>org.springframework.hateoas</groupId>
  <artifactId>spring-hateoas</artifactId>
</dependency>

После:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
person Michael Hegner    schedule 03.04.2019