Introduction:
A Classpath scanning basically means, detecting the classes that need to be managed by the Spring under a specified package. You need to make use of the spring @ComponentScan annotation with the @Configuration for classpath scanning. This annotation allows you to specify a base package and also a filter if needed to fine control the package scanning. We will look into both the approaches in this article.
Inside look at @ComponentScan annotation
Before learning to use this annotation, let us take a look at this annotation and understand the parameters it accepts. I have highlighted the most used parameters.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class; ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT; String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN; /** * Indicates whether automatic detection of classes annotated with * {@code @Component} {@code @Repository}, {@code @Service}, * or {@code @Controller} should be enabled. */ boolean useDefaultFilters() default true; Filter[] includeFilters() default {}; Filter[] excludeFilters() default {}; boolean lazyInit() default false; }
We will explore each of these, will use @ComponentScan without specifying basePackages value, then use it with a base package value. After this, we will also learn to use custom filters.
Use the @ComponentScan annotation
- The
@ComponentScan
can be used along with the XML<context:component-scan base-package=""/>
configuration.
1. Use @ComponentScan with arguments
The simple way to use this annotation is to use it with the @Configuration or with the application configuration class and specify the base package in it. GitHub link to the below code.
package basic.ioc.autowire; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import java.util.Random; import java.util.UUID; @Configuration @ComponentScan("basic.ioc.autowire") public class AutowireBeanConfig { //Other configs inside. }
It is also possible to provide a list of base classes as shown below.
@Configuration @ComponentScan(basePackages = {"basic.ioc.autowire", "basic.ioc.setter"}) public class AutowireBeanConfig { //other configs }
2. Use @ComponentScan without an argument
Like mentioned before, it is optional to specify the basePackage value. When used without an argument, you will have less control over the package scanning.
@Configuration @ComponentScan public class DemoAppConfig { //... }
NOTE: The location where @ComponentScan is put, the scanning starts from its package by default.
3. Use @ComponentScan in a Spring-Boot application
In a Spring-Boot application, we don’t need to specify the @Configuration annotation unless we want more control over the classpath scanning. This is because of the @SpringBootApplication
, which is already a combination of below listed three annotations.
@Configuration @EnableAutoConfiguration @ComponentScan
In a typical Spring-Boot app the @SpringBootApplication
annotation is present in a base level package, hence everything under that package gets auto-detected.
4. Use Filters with @ComponentScan
The default filters in @ComponentScan
effectively detects the stereotype annotations – @Component, @Repository, @Service, @Controller, @RestController, and the meta-annotation @Configuration. It is also possible to disable this default filter as below.
@ComponentScan(basePackages = "com.jbd.app", useDefaultFilters=false)
Let’s say we want to disable the detection of @Repository annotated class, instead include the classes that have a Dao
in their name e.g. StudentDao.
@Configuration @ComponentScan(basePackages = "com.jbd", includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Dao"), excludeFilters = @Filter(Repository.class)) public class AppConfig { ... }
It is also possible to have the same in XML based configurations.
<beans> <context:component-scan base-package="com.jbd"> <context:include-filter type="regex" expression=".*Dao"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> </beans>
Conclusion:
I have explained the ways in which you can use the @ComponentScan annotation to auto scan the classes and manage them as beans in Spring.
Leave A Comment