问题
I am trying to migrate to javaConfig using the following configuration:
WebMvcConfig:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.bignibou" }, useDefaultFilters = false,
includeFilters = { @Filter(type = FilterType.ANNOTATION, value = Controller.class),
@Filter(type = FilterType.ANNOTATION, value = ControllerAdvice.class) })
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(converter());
addDefaultHttpMessageConverters(converters);
}
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(currentMemberHandlerMethodArgumentResolver());
super.addArgumentResolvers(argumentResolvers);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/", "classpath:/META-INF/web-resources/");
super.addResourceHandlers(registry);
}
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/cgv").setViewName("conditions/cgv");
super.addViewControllers(registry);
}
@Bean
public ConversionService conversionService() {
return new ApplicationConversionServiceFactoryBean().getObject();
}
@Bean
public MappingJacksonHttpMessageConverter converter() {
MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
converter.setObjectMapper(objectMapper());
return converter;
}
@Bean
public CustomJacksonObjectMapper objectMapper() {
return new CustomJacksonObjectMapper();
}
@Bean
public CurrentMemberHandlerMethodArgumentResolver currentMemberHandlerMethodArgumentResolver() {
return new CurrentMemberHandlerMethodArgumentResolver();
}
@Bean
public FixedLocaleResolver fixedLocaleResolver() {
FixedLocaleResolver fixedLocaleResolver = new FixedLocaleResolver();
fixedLocaleResolver.setDefaultLocale(Locale.FRENCH);
return fixedLocaleResolver;
}
@Bean
public ThymeleafTilesConfigurer tilesConfigurer() {
ThymeleafTilesConfigurer tilesConfigurer = new ThymeleafTilesConfigurer();
tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/tiles-defs.xml", "/WEB-INF/web-templates/**/views.xml" });
return tilesConfigurer;
}
}
Main config:
@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = "com.bignibou",
excludeFilters = { @Filter(type = FilterType.CUSTOM, value = RooRegexFilter.class),
@Filter(type = FilterType.ANNOTATION, value = Controller.class) })
public class MiscellaneousConfiguration {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("META-INF/i18n/application", "META-INF/i18n/messages", "META-INF/i18n/mail-templates", "META-INF/i18n/validation-messages");
return messageSource;
}
@Bean
public PropertyPlaceholderConfigurer properties() throws IOException {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/i18n/*.properties"));
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
return localValidatorFactoryBean;
}
}
And finally my custom regex filter:
public class RooRegexFilter extends RegexPatternTypeFilter {
public RooRegexFilter() {
super(Pattern.compile(".*_Roo_.*"));
}
}
I get errors such as BeanCreationException and NoSuchBeanDefinitionException as follows:
nov. 03, 2013 3:58:48 PM org.apache.catalina.core.ApplicationContext log
Grave: StandardWrapper.Throwable
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchEngineController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bignibou.service.searchEngine.SearchEngineService com.bignibou.controller.searchEngine.SearchEngineController.searchEngineService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bignibou.service.searchEngine.SearchEngineService] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:505)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1091)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bignibou.service.searchEngine.SearchEngineService com.bignibou.controller.searchEngine.SearchEngineController.searchEngineService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bignibou.service.searchEngine.SearchEngineService] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 26 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bignibou.service.searchEngine.SearchEngineService] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 28 more
nov. 03, 2013 3:58:48 PM org.apache.catalina.core.StandardContext loadOnStartup
Grave: La servlet /bignibou a généré une exception "load()"
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bignibou.service.searchEngine.SearchEngineService] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:505)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1091)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
I suspect something is wrong with my @ComponentScan configuration. Can anyone please help?
edit 1: here is my web.xml-equivalent:
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
rootContext.setConfigLocations(new String[] { "classpath*:META-INF/spring/applicationContext*.xml" });
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.addListener(RequestContextListener.class);
servletContext.addListener(HttpSessionEventPublisher.class);
servletContext.setInitParameter("defaultHtmlEscape", "true");
FilterRegistration.Dynamic fr;
fr = servletContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter());
fr.setAsyncSupported(Boolean.TRUE);
fr.addMappingForUrlPatterns(null, true, "/*");
fr = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter());
fr.setAsyncSupported(Boolean.TRUE);
fr.setInitParameter("encoding", "UTF-8");
fr.setInitParameter("forceEncoding", "true");
fr.addMappingForUrlPatterns(null, true, "/*");
fr = servletContext.addFilter("Spring OpenEntityManagerInViewFilter", new OpenEntityManagerInViewFilter());
fr.setAsyncSupported(Boolean.TRUE);
fr.addMappingForUrlPatterns(null, true, "/*");
fr = servletContext.addFilter("springSecurityFilterChain", new org.springframework.web.filter.DelegatingFilterProxy());
fr.setAsyncSupported(Boolean.TRUE);
fr.addMappingForUrlPatterns(null, true, "/*");
AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
mvcContext.register(WebMvcConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("bignibou", new DispatcherServlet(mvcContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
回答1:
The best resource for Java Configuration is the Spring documentation.
It doesn't seem like you are registering your MiscellaneousConfiguration
class anywhere. Change this bit
AnnotationConfigApplicationContext rootContext = new AnnotationConfigApplicationContext(MiscellaneousConfiguration.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
I don't know what your XML config was scanning for but apparently it wasn't adding a SearchEngineService
bean to the context. Since there is no SearchEngineService
bean in the context to autowire into the SearchEngineController
bean, context initialization will fail.
Note that only your servlet (@WebMvc
) config should scan for @Controller
. Make your @ComponentScan
basePackages
more specific so that bean definitions for the same class don't overwrite each other.
Also, you will want to make this @Bean
method static
@Bean
public static PropertyPlaceholderConfigurer properties() throws IOException {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/i18n/*.properties"));
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
PropertyPlaceholderConfigurer
is a BeanFactoryPostProcessor
. You can read about why you have to do this in the @Bean javadoc.
来源:https://stackoverflow.com/questions/19754374/issue-with-componentscan-filters-since-migrating-to-javaconfig