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.