I have a Spring Boot application with the following structure
com.package
Application - annotated with @SpringBootApplication
Configuration - annotated with @Configuration
Component1 - annotated with @Component, constructor annotated with @Autowired
com.package.subpackage
Component2 - annotated with @Component, constructor annotated with @Autowired
My application class is
package com.package;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
When I start the application both Component1
and Component2
are identified as candidate components. However, only Component1
is instantiated.
Component2
will only instantiate when I make either of the following changes
com.package
i.e. the same as Component1
@Autowired
field in com.package.Configuration
Why does Spring Boot discover the component but not instantiate it in this case? Are there differences in how @ComponentScan
works with regards to discovering vs instantiating @Component
?
No. It is used to explicitly declare a single bean, rather than letting Spring do it automatically. If any class is annotated with @Component it will be automatically detect by using classpath scan. We should use @bean, if you want specific implementation based on dynamic condition.
I have added 2 main classes with @SpringBootApplication.
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 Auto Configuration automatically configures your Spring application based on the JAR dependencies you added in the project. For example, if MySQL database is on your class path, but you have not configured any database connection, then Spring Boot auto configures an in-memory database.
In my case it was not an issue with Spring Boot itself.
The @PostConstruct
method for Component1
was blocking the main thread hence Component2
was not initialised.
Using @Autowired
or moving to the same package obviously triggered the @PostConstruct
method of Component2
before Component1
.
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