Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ComponentScan.basePackageClasses vs ComponentScan.basePackages to register a single Spring webMVC Controller?

I want to add a single specific controller class to my Spring WebApplicationContext. I ran across the following example: (its in Scala, but is adapted from here: using ComponentScan or context:component-scan with only one class)

@Configuration 
@ComponentScan(
  basePackages = Array("com.example.controllers"),
  useDefaultFilters = false,
  includeFilters = Array(
    new ComponentScan.Filter(`type` = FilterType.ASSIGNABLE_TYPE,
      value = Array(classOf[com.example.controllers.MyController]))))
class MyConfig {
}

This works nicely (but is very verbose). But Spring's @ComponentScan also has basePackageClasses

@Configuration 
@ComponentScan( basePackageClasses=Array(classOf[com.example.controllers.MyController])) 
class MyConfig {
}

Of basePackageClasses, Spring's docs says:

Type-safe alternative to basePackages() for specifying the packages to
scan for annotated components.

However, while the first ComponentScan correctly adds only com.example.controllers.MyController, but the second cause all of my @Controller to be scanned and added! Why? What's the use of basePackageClasses?

Example like: https://github.com/mikaelhg/springmvc-example/blob/master/src/main/java/mikaelhg/example/ExampleConfiguration.java suggest that basePackageClasses can be used to load a single component.


Update:

As an aside, replacing:

@Configuration 
@ComponentScan(
  basePackages = Array("com.example.controllers"),
  useDefaultFilters = false,
  includeFilters = Array(
    new ComponentScan.Filter(`type` = FilterType.ASSIGNABLE_TYPE,
      value = Array(classOf[com.example.controllers.MyController]))))
class MyConfig {
}

with

@Configuration 
class MyConfig {

  @Bean
  var myController = new com.example.controllers.MyController

}

it seems that MyController never gets gets connected to the servlet (the behavior changed to 404-NotFound) -- when added to a WebApplicationContext.

like image 367
user48956 Avatar asked Jun 09 '14 22:06

user48956


1 Answers

The full javadoc for that attribute reads

Type-safe alternative to basePackages() for specifying the packages to scan for annotated components. The package of each class specified will be scanned.

Consider creating a special no-op marker class or interface in each package that serves no purpose other than being referenced by this attribute.

By type-safe, you can't make any mistakes with the String value of the name of the package. If you specify an incorrect class, it will fail at compile time.

When you specify basePackageClasses, Spring will scan the package (and subpackages) of the classes you specify. This is a nice trick with no-op classes/interfaces like Controllers, Services, etc. Put all your controllers in one package containing the Controllers class and specify your Controllers class in the basePackageClasses. Spring will pick them all up.

You still need to specify the filters.

like image 144
Sotirios Delimanolis Avatar answered Oct 13 '22 20:10

Sotirios Delimanolis