background
On the SpringBoot startup class, there are three ways to configure the scan package path. Recently, I saw that all three annotations were used in an application. The code is as follows:
@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer
}
So, the question is: In SpringBoot, what are the effective priorities of these three annotations, and is there any difference between the first and the second? This article summarizes the precautions for these three annotations.
SpringBootApplication annotation
This is SpringBoot's annotation, which is essentially the sum of three Spring annotations.
-
@Configuration
-
@EnableAutoConfiguration
-
@ComponentScan
By default, it scans the package where the startup class is located and all its sub-packages, but does not include other directories of third-party jar packages. The scanBasePackages
scan package path can be reset through properties.
Note: If we need to scan the annotations in the dependent jar package, and the path of the dependent package is not included in the SpringBoot startup classpath, we need to use the @ComponentScan
annotation to scan the third-party package alone. At the same time, the scan path of this project must be specified, because once there is this annotation, it will take precedence, and the default scan package will be invalid.
For example, this project:
The project directory of the SpringBoot startup class is the directory of the cn.com.a.b
referenced third-party public package , so the annotations in the third-party jar package can be scanned directly. In other jar packages, if there are annotations, they cannot be scanned.xxx.common.jar
cn.com.a.b
ComponentScan annotation
This is an annotation of the Spring framework, which is used to specify the component scanning path. If this annotation is used, its value must contain all the paths that need to be scanned in the entire project. Because it will override SpringBootApplication
the default scan path, causing it to fail.
There are two types of failures:
First, if ComponentScan
only one value is included and it is the default startup class directory, it will SpringBootApplication
take effect, the ComponentScan
annotation will be invalid, and an error will be reported:
Second, if you ComponentScan
specify multiple specific subdirectories, SpringBootApplication
it will be invalid at this time, and Spring will only scan ComponentScan
the annotations in the specified directory. If you happen to have Controller classes outside the directory, unfortunately, those controllers will not be accessible.
Back to the code at the beginning:
@SpringBootApplication(scanBasePackages ={})
@ComponentScan(basePackages = {})
ComponentScan
After the annotation is specified here , scanBasePackages
it will be invalid. Therefore, if ComponentScan
the basePackages
value does not include cn.com.a.b
the package where the startup class is located, and only specifies the directory of the third-party jar, then any annotations under this project cannot be scanned.
MapperScan annotations
This is the annotation of MyBatis, which will encapsulate all DAO classes in the specified directory into MyBatis BaseMapper
classes, and then inject them into the Spring container. The injection can be completed without additional annotations.
Revelation
The SpringBoot package scan path, the conflicting behavior of the two annotations, I have repeatedly verified the phenomenon for a long time, but I have not found a reasonable explanation. This article has been brewing in the draft box for almost two weeks and has been on hold.
I found an article today saying that when the two are used at the same time, SpringBootApplication
they will fail. So far, the doubts about the SpringBoot scan path are finally eliminated.