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;
It's not mandatory to define default constructor, but if you are writing Hibernate persistent class, JPA entities, or using the Spring framework to manage object creation and wiring dependencies, you need to be a bit careful.
Spring Boot @SpringBootApplication annotation is used to mark a configuration class that declares one or more @Bean methods and also triggers auto-configuration and component scanning. It's same as declaring a class with @Configuration, @EnableAutoConfiguration and @ComponentScan annotations.
Spring Boot automatically configures your application based on the dependencies you have added to the project by using @EnableAutoConfiguration annotation. For example, if MySQL database is on your classpath, but you have not configured any database connection, then Spring Boot auto-configures an in-memory database.
Like any other java class SpringApplication class can be created using constructor. In this case, You have a constructor that takes zero or more source classes. So you could rewrite the previous snippet as shown here. With this approach, You could change Custom Banner, Lazy loading and Application Startup monitoring etc. directly.
That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice. However, depending on what type of IoC you use for that specific bean, you may need a default (empty) constructor.
The SpringApplication class provides a convenient way to bootstrap a Spring application from a main () method. In most cases, you would use the static run method of this class as shown below. When you run this main method, You will see the following output.
You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With