15

I have a boot application and in one of my facades I try to Autowire the conversionService like this:

@Autowired
private ConversionService conversionService;

as a result I get this:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.core.convert.ConversionService] is defined: expected single matching bean but found 3: mvcConversionService,defaultConversionService,integrationConversionService
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1061)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 16 more

To overcome this I have added a Qualifier lilke this:

@Autowired
@Qualifier("mvcConversionService")
private ConversionService c;

and this all works. However all my custom converters are automatically added the to the mvcConversionService. And now I want to extend the ConversionService and add another method to it, however my converters are again added the to the mvcConversionService. Is there a way to tell spring-boot which conversionService to use to automatically register my converters there? I don't want to manually list all the converters to the new conversionService.

Petar Tahchiev
  • 4,336
  • 4
  • 35
  • 48
  • Did you ever find a better solution for this? Trying to implement Spring Cloud Config Server and a `integrationConversionService` just showed up – David Welch May 06 '15 at 22:21
  • Possible duplicate of [How to Autowired in ConversionService in springboot](http://stackoverflow.com/questions/30039619/how-to-autowired-in-conversionservice-in-springboot) – Christian Vielma Nov 01 '15 at 13:01
  • Did you add dependency of "org.springframework.integration:spring-integration-ip"? – Namo Jun 25 '19 at 08:31

4 Answers4

1

Explanation

Spring will attempt to auto-create a ConversionService (in your case mvcConversionService) for the application. It has no qualifiers for what Converters will be registered so if you create a component/bean that implements one of the following types, it will be autoregistered to the service.

  1. Converter
  2. GenericConverter
  3. Printer
  4. Parser

Solution #1

Ignore it. If there is no harm done by registering these converters to the mvcConversionService, then it might not be worth your time to work around this restriction. Your converter classes will likely go unused.

Solution #2

Reproduce your own interfaces. You can copy the interface for ConversionService and Converter and name them how you like. Sure, the functionality is intended to be the same but this will prevent your Converter classes from being injected into any other ConversionService instances.

hsoj48
  • 126
  • 4
0

I was experiencing a similar issue. The problem seems to be that you need to define which conversion service you want to use. You can do it by XML or using a Spring Boot configuration.

I'm copying here part of answer to a very similar question (the one that worked for me) and marking this question as possible duplicate.

A look into the Spring documentation reveals, that you should declare a ConversionService bean. In the XML configuration it would look like this:

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="example.MyCustomConverter"/>
        </set>
    </property>
</bean>
Community
  • 1
  • 1
Christian Vielma
  • 15,263
  • 12
  • 53
  • 60
  • How does your answer cope with the constraint in the question? see the constraint below: *I don't want to manually list all the converters to the new `conversionService`* – Adrian Mar 18 '20 at 12:35
0

If its a list of converters you're after and they all implement the same interface you can autowire in a list.

e.g.

@Service
public class MyService {

  @Autowired
  private List<MyConverter> myConverters;

  public void myMethod(MyRawThing thing) {
    myConverters
      .forEach(converter -> converter.doStuff(thing));
  }

}

and them iterate through them as required.

A nice feature of this, is that as new implementations are added, you do not need to update the code that uses them.

jeremyt
  • 510
  • 4
  • 6
0

Bump into this because I was having this issue also with Spring Integration. I'm not so satisfied with this solution but this is a quick one.

@Configuration
public class ConversionServiceConfiguration {

    @Bean
    @Primary
    public ConversionService rewardBoxConversionService(@Qualifier("mvcConversionService") final ConversionService conversionService) {
        return conversionService;
    }

}

Problem will arise if you need other ConversionService implementation for some of your logic. But, that can be solved by using @Qualifier annotation.