Reputation: 7451
I'm using Spring 3.1 and bootstrapping an application using the @Configuration
and @ComponentScan
attributes.
The actual start is done with
new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);
This Configuration class is annotated with
@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass
and this works fine. However I'd like to be more specific about the packages I scan so I tried.
@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass
However this fails with errors telling me it can't find components specified using the @Component
annotation.
What is the correct way to do what I'm after?
Thanks
Upvotes: 116
Views: 248124
Reputation: 21
For @componentScan, One of basePackageClasses(), basePackages() or its alias value() must be specified
Check this: ComponentScan
All these flavours are correct:
@ComponentScan("com.my.package")
@ComponentScan({"com.my.package.first","com.my.package.second"})
@ComponentScan(basePackages = "com.example.myapp.services")
@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})
@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})
Upvotes: 0
Reputation: 45
Use
@ComponentScan(basePackages = {"package1", "package2"})
define it at top before class.
Edit: the brackets must be around all the base packages, not a pair of brackets per package
Upvotes: 1
Reputation: 21
I use:
@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})
Upvotes: 2
Reputation: 1630
Another way of doing this is using the basePackages
field; which is a field inside ComponentScan annotation.
@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})
If you look into the ComponentScan annotation .class from the jar file you will see a basePackages field that takes in an array of Strings
public @interface ComponentScan {
String[] basePackages() default {};
}
Or you can mention the classes explicitly. Which takes in array of classes
Class<?>[] basePackageClasses
Upvotes: 14
Reputation: 81
You can also use @ComponentScans annotation:
@ComponentScans(value = { @ComponentScan("com.my.package.first"),
@ComponentScan("com.my.package.second") })
Upvotes: 3
Reputation: 31
make sure you have added this dependency in your pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Upvotes: 1
Reputation: 6153
@ComponentScan uses string array, like this:
@ComponentScan({"com.my.package.first","com.my.package.second"})
When you provide multiple package names in only one string, Spring interprets this as one package name, and thus can't find it.
Upvotes: 192
Reputation: 53
You use ComponentScan to scan multiple packages using
@ComponentScan({"com.my.package.first","com.my.package.second"})
Upvotes: 5
Reputation: 3546
There is another type-safe alternative to specifying a base-package location as a String. See the API here, but I've also illustrated below:
@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})
Using the basePackageClasses specifier with your class references will tell Spring to scan those packages (just like the mentioned alternatives), but this method is both type-safe and adds IDE support for future refactoring -- a huge plus in my book.
Reading from the API, Spring suggests creating a no-op marker class or interface in each package you wish to scan that serves no other purpose than to be used as a reference for/by this attribute.
IMO, I don't like the marker-classes (but then again, they are pretty much just like the package-info classes) but the type safety, IDE support, and drastically reducing the number of base packages needed to include for this scan is, with out a doubt, a far better option.
Upvotes: 53