Suppose I have a jar with a Spring Component called MyComponent. This jar is a Spring Boot "autoconfigured" jar, meaning that it has a Configuration class (annotated with @Configuration), and additionally, a META-INF/spring.factories file on the classpath. This jar is not an executable jar by itself; it is a library that is meant for inclusion in a Spring Boot application.
These files look as follows:
MyComponent.java, in package com.mine.components:
@Component
public class MyComponent {
private static final Logger logger = LoggerFactory.getLogger(MyComponent.class);
@PostConstruct
public void init() {
logger.info("MyComponent inited");
}
}
MyConfiguration.java, in package com.mine.config:
@Configuration
@ComponentScan(basePackages = "com.mine.components")
public class MyConfiguration {
}
spring.factories, in META-INF under src/main/resources:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.mine.config.MyConfiguration
If I include this jar in a Spring Boot project with the above three files, the MyComponent component is NOT detected (the log message never prints).
But if I instead remove the @ComponentScan and declare MyComponent using the @Bean annotation as follows, it is detected:
@Bean
public MyComponent myComponent() {
return new MyComponent();
}
Why?
Difference beetween ComponentScan and declared Bean inside @Configuration class:
@ComponentScan: You enable auto-scanning (default using current folder path), optionally you can specify an basePackage where spring will found yours beans.
@ComponentScan(basePackages = "com.mine.components") You're saying to Spring that in this package("com.mine.components"), you'll define yours beans typically using annotations (@Component, @Entity, @Controller, @Service, @Repository or more).
@Bean: This way you define your beans manually inside @Configuration class, but Spring has to discover your configuration class, usually using @ComponentScan, @SpringBootApplication.
META-INF/spring.factories: you define an custom autoconfiguration