0

I am working through Spring MVC and I have many Formatter<T> classes, something like this

@Component
public class DeporteFormatter implements Formatter<Deporte> {

   ...

   @Autowired
   public DeporteFormatter(SomeDependency someDependency){
      this.someDependency = someDependency;
   }

I have my customized MvcInfrastructureConfiguration class

@EnableWebMvc
@Configuration
@ComponentScan(basePackages={"..."})
public class MvcInfrastructureConfiguration extends WebMvcConfigurerAdapter {

    private Set<Formatter<?>> formatters;

    ...

    @Override
    public void addFormatters(FormatterRegistry registry) {

        if(formatters==null)
            logger.error("dependency is null");

        logger.info("formatters.size(): {}", formatters.size());

        for(Formatter<?> formatter : formatters){
            registry.addFormatter(formatter);
        }

    }

    ...

I am confused with the following:

If I use

//Mandatorily asked for by Spring
public MvcInfrastructureConfiguration(){
    logger.info("MvcInfrastructureConfiguration Constructor...");
}

@Autowired
public MvcInfrastructureConfiguration(Set<Formatter<?>> formatters){
    logger.info("MvcInfrastructureConfiguration Constructor with parameter");
    this.formatters = formatters;
}

the formatters instance variable never is injected and I get a NullPointerException..

But if I use

@Autowired
private Set<Formatter<?>> formatters;

//Mandatorily asked for by Spring
public MvcInfrastructureConfiguration(){
    logger.info("MvcInfrastructureConfiguration Constructor...");
}


//public MvcInfrastructureConfiguration(Set<Formatter<?>> formatters){
    //logger.info("MvcInfrastructureConfiguration Constructor with parameter");
    //this.formatters = formatters;
//}

All works fine..

Why? I thought @Autowired should work without matter his location (of course is bad practice use it in instance variables in not infrastructure beans due the problems with Testing)

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
  • 1
    `@Configuration` annotated classes are a bit special. They are processed using byte code techniques I would suspect that this also has an influence on what types of constructors you can use. If you want a dependency in that class just use field injection or method inject (i.e. use it as a method argument and it will be passed in). – M. Deinum Sep 15 '14 at 05:16
  • Has sense, thanks by the reply. About `method inject (i.e. use it as a method argument and it will be passed in)` do you mean something like `register.addFormatter(getFormatter())`, it through JavaConfig + `@Bean`? – Manuel Jordan Sep 15 '14 at 12:09
  • 1
    No and in this particular case it won't work either. But you can create a method which takes an argument and Spring will try to inject it. Something like `public Dao myDao(DataSource ds)`. Spring will try to find a `DataSource` to inject into that method. – M. Deinum Sep 15 '14 at 12:35
  • Has sense. Thank You – Manuel Jordan Sep 15 '14 at 13:16

0 Answers0