In this tutorial we will explain what is Component Scanning in Spring and how to use @ComponentScan annotation in Spring and Spring Boot applications.
1. What is component scan?
The process of discovering Spring Components within classpath of the application is called Component Scanning in Spring. Later spring will use them to add in application context.
The classes annotated with @Component, @Controller, @Service, @Repository, @Configuration, @RestController etc will be treated as Spring Components.
2. @ComponentScan annotation
@ComponentScan annotation tells Spring that where to look for Spring Components explicitly. @ComponentScan annotation is used with @Configuration annotation.
3. Using @ComonentScan without attribute
@ComonentScan without attribute tells that Spring to discover components in current package and within it’s sub packages. Let’s have look at following example, component classes available in reptiles
base package and in crocodles
, snakes
sub-packages, they are annotated with @Component.
@ComponentScan @Configuration public class ComponentScanNoAttributeConfig { }
Testing :
public class ComponentScanNoAttributeConfigTest { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ComponentScanNoAttributeConfig.class); String[] springComponents = ctxt.getBeanDefinitionNames(); for (String bean : springComponents) System.out.println(bean); } }
If you run above program, you will see following classes are available in application context.
componentScanNoAttributeConfig crocodle snake turtle dwarfCrocodle nileCrocodle orinocoCrocodle siameseCrocodle blackMamba capeCobra easternGreenMamba egyptianCobra equatorialCobra monocledCobra
4. Using @ComponentScan in Spring Boot
In Spring Boot application we use @SpringBootApplication annotation to start the application. But it’s combination of @Configuration, @EnableAutoConfiguration and @ComponentScan annotations. In Spring Boot applications, component scanning happen implicitly.
Let’s create SpringBootApp
class in reptiles
package and configure @SpringBootApplication.
@SpringBootApplication public class SpringBootApp { public static void main(String[] args) { ConfigurableApplicationContext ctxt = SpringApplication.run(SpringBootApp.class, args); String[] beans = ctxt.getBeanDefinitionNames(); for(String bean : beans) System.out.println(bean); } }
Disable ComponentScanNoAttributeConfig
and run the above program, you will see following spring beans in application context.
crocodle snake turtle dwarfCrocodle nileCrocodle orinocoCrocodle siameseCrocodle blackMamba capeCobra easternGreenMamba egyptianCobra equatorialCobra monocledCobra ... other spring internal beans
5. @ComonentScan with attribute
We can tell Spring to which packages to scan specifically by using basePackages attribute. Let’s see few examples.
Following are the complete list of Components available in the sample project.
5.1. Scanning Base Packages using @ComonentScan
Following example demonstrates how to scan components only within reptiles
and its sub packages specifically.
@Configuration @ComponentScan(basePackages = "com.javabydeveloper.spring.bean.animal.reptiles") public class ReptilesConfig { }
Testing:
public class ReptilesConfigDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ReptilesConfig.class); String[] springComponents = ctxt.getBeanDefinitionNames(); for(String bean : springComponents) System.out.println(bean); } }
Results:
reptilesConfig crocodle snake turtle dwarfCrocodle nileCrocodle orinocoCrocodle siameseCrocodle blackMamba capeCobra easternGreenMamba egyptianCobra equatorialCobra monocledCobra
5.2. Scanning Multiple Packages
We can specify multiple packages using basePackages attribute. Let’s see an example.
@Configuration @ComponentScan(basePackages = {"com.javabydeveloper.spring.bean.animal.amphibians", "com.javabydeveloper.spring.bean.animal.reptiles.crocodles"}) public class ScanMultiplePackageConfig { }
Testing:
public class ScanMultiplePackageConfigDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ScanMultiplePackageConfig.class); String[] springComponents = ctxt.getBeanDefinitionNames(); for(String bean : springComponents) System.out.println(bean); } }
Results:
scanMultiplePackageConfig frog newt toad dwarfCrocodle nileCrocodle orinocoCrocodle siameseCrocodle
5.3. Using basePackageClasses attribute
basePackageClasses is type-safe alternative to basePackages for specifying the packages to scan for annotated components. The package of each class specified will be scanned. In following example BlackMamba
belongs to snakes
package and Frog
belongs to amphibians
package.
@Configuration @ComponentScan(basePackageClasses = {BlackMamba.class, Frog.class}) public class ScanBasePackageClassesConfig { }
Testing:
public class ScanBasePackageClassesConfigDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ScanBasePackageClassesConfig.class); String[] springComponents = ctxt.getBeanDefinitionNames(); for(String bean : springComponents) System.out.println(bean); } }
Results:
blackMamba capeCobra easternGreenMamba egyptianCobra equatorialCobra monocledCobra frog newt toad
6. Conclusion
In this tutorial, we have learned what is component scan in Spring and how to discover components using @ComponentScan annotation.
You can get source code at our GitHub repository.
7. References
Other Related Tutorials:
- Spring @Autowired
- Spring @Lazy
- Spring Boot XML Configuration
- Spring Injecting Collection
- Spring @Order
- Spring @Primary
- Spring @Import
- Spring @ComponentScan Filter Types