简体   繁体   中英

Spring Web Mvc configuration initialization

I'm trying to configure a stack of libraries through spring java @Configuration .
On one of the tops of all I have a Spring Web Mvc application.

To configure the application I used an extension of the AbstractAnnotationConfigDispatcherServletInitializer ; from there I referenced another @Configuration class for the underlying layers in the getRootConfigClasses() method and, for the servlet container, I used the getServletConfigClasses() method to reference an extension of the WebMvcConfigurationSupport .

All works well (the web MVC part) until I need some beans from the underlying layers from classes instantiated at the WebMvcConfigurationSupport level (interceptors, and so on); In those classes all the references to beans that should be initialized in the underlying layers (that are classes annotated with @Component ) with the @Autowired annotation give me null .

In another application on top of the same stack of layers (a service layer without MVC) all is working good.

Any suggestions?

EDIT

If I load a bean (via the @Bean annotation) from the root configuration class autowiring works.
If I load a bean (via the @Bean annotation) from the servlet (WebMvc) configuration class autowiring doesn't work.

It seems they're two different Spring contexts.

SOME CODE

The interceptor

package my.package.interceptor;

@Component
public class AuthenticationInterceptor extends HandlerInterceptorAdapter {...}

The root config

package my.package;

@Configuration
@ComponentScan(
            basePackageClasses={ UnderlyingLayersSpringConfiguration.class }, 
            basePackages = {"my.package.interceptor"}
)

public class WebSpringConfiguration {...}

The MVC config

package my.package;

@Configuration
@EnableWebMvc
@ComponentScan(
            basePackageClasses = WebSpringConfiguration.class, 
            basePackages = {"my.package.interceptor"}, 
            includeFilters = @Filter(Controller.class) , 
            useDefaultFilters = false
            )
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private AuthenticationInterceptor authenticationInterceptor;
}

The web app initializer: 2 versions
Version 1

package my.package;

public class WebAppInitializer 
extends AbstractAnnotationConfigDispatcherServletInitializer 
implements WebApplicationInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { WebSpringConfiguration.class, WebMvcConfig.class };

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
}

Version 2

package my.package;

public class WebAppInitializer 
extends AbstractAnnotationConfigDispatcherServletInitializer 
implements WebApplicationInitializer {

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

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

The error

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [my.package.interceptor.AuthenticationInterceptor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I found the issue and I report the answer here, for future memory and to allow others to check this aspect of spring configurations when having the same problem.

The underlying layer's beans inherit from a structure of classes where spring @Profile was used.

I was unable to load beans because on the topmost project I didn't specify a @Profile , so no profile, no beans.

Quite simple, the time one considers it.

Hope this can help someone.

The root context and dispatcher servlet context are indeed two different contexts. The root context is the parent of the servlet context.

You probably did not specify the @ComponentScan annotation on the class configuring the servlet context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM