Why does @ComponentScan behave differently for different configuration files?

I’m relatively new to Spring, and was following some examples.

During one of the examples I noticed that Spring wasn’t mapping URI to methods.

I discovered that I put my @ComponentScan annotation on the wrong configuration class and fixed my problem.

So my question is why @ComponentScan works for one of these classes and not with the other?

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"org.zerock.controller"}) // This Works.
public class ServletConfig implements WebMvcConfigurer {
    @Bean
    public MultipartResolver multipartResolver(){
        return new StandardServletMultipartResolver();
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        registry.viewResolver(resolver);
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
}



@Configuration
//@ComponentScan(basePackages = {"org.zerock.controller"}) This Doesn't Work
public class RootConfig {
}



// How the two configuration classes are initialized
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{ServletConfig.class};
    }



I’ve read that root config classes and servlet classes are set up differently in the application context hierarchy.

I suspect that has something to do with this, but I fail to see how that would cause this.

Answer

Javadoc for AbstractAnnotationConfigDispatcherServletInitializer recommend to implement:

getRootConfigClasses() — for “root” application context (non-web infrastructure) configuration. getServletConfigClasses() — for DispatcherServlet application context (Spring MVC infrastructure) configuration.

If an application context hierarchy is not required, applications may return all configuration via getRootConfigClasses()

So a @ComponentScan on the RootConfig should work if there are no duplication on the ServletConfig level.

Could you post the error you get and all classes?

I recommend you to place the RootConfig in the root of you packages and use @ComponentScan without specifying base package.