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
This question is related to
java
spring
annotations
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
You use ComponentScan to scan multiple packages using
@ComponentScan({"com.my.package.first","com.my.package.second"})
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.
Provide your package name separately, it requires a String[]
for package names.
Instead of this:
@ComponentScan("com.my.package.first,com.my.package.second")
Use this:
@ComponentScan({"com.my.package.first","com.my.package.second"})
I use:
@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})
You can also use @ComponentScans annotation:
@ComponentScans(value = { @ComponentScan("com.my.package.first"),
@ComponentScan("com.my.package.second") })
make sure you have added this dependency in your pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Source: Stackoverflow.com