background

There are three ways to configure the scan package path on the SpringBoot boot class. Recently, I saw an application using all three annotations, the code is as follows:

@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer 
}
Copy the code

So, the question is: what is the priority of these three annotations in SpringBoot, and is there any difference between the first and second annotations? This article will sort out the three notes.

SpringBootApplication annotations

This is the SpringBoot annotation, which is essentially the sum of three Spring annotations

  1. @Configuration
  2. @EnableAutoConfiguration
  3. @ComponentScan

By default, it scans the startup class package and all its subpackages, but does not include other directories of third-party JAR packages. You can reset the package path by using the scanBasePackages property.

Note: If we need to scan for annotations in a dependent JAR package whose path is not included in the SpringBoot startup classpath, we use the @ComponentScan annotation alone to scan for third-party packages. The project scan path must also be specified, because once this annotation is present, it takes precedence and the default scan package is invalid.

For example, this project:The project directory of the SpringBoot boot class iscn.com.a.b, reference to the third party public packagexxx.common.jarThe directory ofcn.com.a.bAnnotations in third-party JAR packages can naturally be scanned directly. Other JAR packages that have annotations cannot be scanned.

ComponentScan annotations

This is the Spring framework annotation that specifies the component scan path. If you use this annotation, its value must contain all the paths that need to be scanned throughout the project. Because it overrides the default scan path of SpringBootApplication, it becomes invalidated.

There are two kinds of failure manifestations:

One, ifComponentScanContains only one value and is the default startup class directory,SpringBootApplicationTo take effect,ComponentScanAnnotation invalid, error reported:Second, ifComponentScanSpecify multiple concrete subdirectoriesSpringBootApplicationWill fail, Spring will only scanComponentScanSpecify an annotation under the directory. If you happen to have Controller classes outside the directory, unfortunately, those controllers will not be accessible.

Go back to the code at the beginning:

@SpringBootApplication(scanBasePackages ={})
@ComponentScan(basePackages = {})
Copy the code

ScanBasePackages are invalidated with the specified ComponentScan annotation. Therefore, if the basePackages value for ComponentScan does not include cn.com.a.b, which is the package in which the startup class is located, and only specifies the directory of the third-party JAR, then any annotations under the project will not be scanned.

MapperScan annotations

This is MyBatis annotation. It will encapsulate all DAO classes in the specified directory into MyBatis BaseMapper class, and then inject it into Spring container. No additional annotation is required to complete the injection.

The revelation of

SpringBoot package scanning path, two annotation conflict behavior, I repeatedly verified for a long time to determine the phenomenon, but did not find a reasonable explanation. The article has been sitting in the draft box for almost two weeks.

SpringBootApplication fails when both are used at the same time.