2
votes

I am using Spring Boot with Java programmatic configuration. I am using Spring's ConversionService and several custom implementations of Spring's Converter interface. I would like to register all of converters with my ConversionService bean at configuration time. The catch is that some of these converters have their own annotation-configured dependencies, and these are not being wired. For instance the configuration class is something like the following:

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter
{
    @Bean
    public ConversionService conversionService(List<Converter> converters)
    { 
         DefaultConversionService conversionService = DefaultConversionService();
         for (Converter converter: converters)
         {
             conversionService.addConverter(converter);
         }
         return conversionService;
    }
}

And some of the converter implementations may be as follows:

@Component
public class ConverterImpl implements Converter 
{ 
     @Autowired
     private DependentClass myDependency;

     //The rest of the implementation
}

Although the conversionService is having every Converter implementation added to it via the configuration class, none of the autowired fields in the converter implementations are being populated. They are null.

My current solution is as follows:

@Component
public class ConverterImpl implements Converter 
{ 
     @Lazy
     @Autowired
     private DependentClass myDependency;

     //The rest of the implementation
}

In short, all autowired fields in the converter implementations are also annotated as 'Lazy'. This seems to work as the fields are populated when they are first accessed. This feels like a hack though. My questions are: Is there a better way of achieving what I want? Am I missing something in the Spring documentation? Is the overall approach flawed?

1

1 Answers

1
votes

I don't think that's a hack, but it isn't guaranteed to always work. The only other way of doing it would be to create your Converters in a separate ApplicationContext, e.g. a parent context. Remember that the ConversionService will be used to create bean definitions and convert dependencies before injecting them, so it has to be available before any other beans are created (hence your problem with the null dependencies).