10

I wonder why the field injection works in the @SpringBootApplication class and the constructor injection does not.

My ApplicationTypeBean is working as expected but when I want to have a constructor injection of CustomTypeService I receive this exception:

Failed to instantiate [at.eurotours.ThirdPartyGlobalAndCustomTypesApplication$$EnhancerBySpringCGLIB$$2a56ce70]: No default constructor found; nested exception is java.lang.NoSuchMethodException: at.eurotours.ThirdPartyGlobalAndCustomTypesApplication$$EnhancerBySpringCGLIB$$2a56ce70.<init>()

Is there any reason why it does not work at @SpringBootApplication class?


My SpringBootApplication class:

@SpringBootApplication
public class ThirdPartyGlobalAndCustomTypesApplication implements CommandLineRunner{

@Autowired
ApplicationTypeBean applicationTypeBean;

private final CustomTypeService customTypeService;

@Autowired
public ThirdPartyGlobalAndCustomTypesApplication(CustomTypeService customTypeService) {
    this.customTypeService = customTypeService;
}

@Override
public void run(String... args) throws Exception {
    System.out.println(applicationTypeBean.getType());
    customTypeService.process();
}

public static void main(String[] args) {
    SpringApplication.run(ThirdPartyGlobalAndCustomTypesApplication.class, args);
}

public CustomTypeService getCustomTypeService() {
    return customTypeService;
}

My @Service class:

@Service
public class CustomTypeService {

    public void process(){
        System.out.println("CustomType");
    }
}

My @Component class:

@Component
@ConfigurationProperties("application.type")
public class ApplicationTypeBean {

    private String type;
Patrick
  • 12,336
  • 15
  • 73
  • 115

1 Answers1

7

SpringBootApplication is a meta annotation that:

// Other annotations
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication { ... }

So baiscally, your ThirdPartyGlobalAndCustomTypesApplication is also a Spring Configuration class. As Configuration's javadoc states:

@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning (typically using Spring XML's element) and therefore may also take advantage of @Autowired/@Inject at the field and method level (but not at the constructor level).

So you can't use constructor injection for Configuration classes. Apparently it's going to be fixed in 4.3 release, based on this answer and this jira ticket.

Community
  • 1
  • 1
Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151