无法使用@EnableWebMvc配置运行SPRING BOOT应用程序

时间:2018-02-10 14:49:35

标签: java spring-mvc spring-boot gradle

我刚接触弹簧靴,我非常有兴趣学习这项技术。这是问题,我有一个带@configuration标签的配置文件。所以当我尝试添加@enablemvc注释或者如果我在spring启动应用程序中添加带有@enablemvc annoation的新文件时,我无法运行该应用程序。如果有人可以帮助我,我真的很感激。

日志

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext@19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.builder.SpringApplicationBuilder.configureAsChildIfNecessary(SpringApplicationBuilder.java:147) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at com.boot.main.ClientMain.main(ClientMain.java:31) [bin/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.9.RELEASE.jar:1.5.9.RELEASE]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext@19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    ... 23 common frames omitted
Caused by: org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext@19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
    at org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry.getHandlerMapping(ResourceHandlerRegistry.java:150) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:446) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe.CGLIB$resourceHandlerMapping$28(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe$$FastClassBySpringCGLIB$$d042f6eb.invoke(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe.resourceHandlerMapping(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    ... 24 common frames omitted
Caused by: java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext@19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
    at org.springframework.web.context.support.WebApplicationObjectSupport.getWebApplicationContext(WebApplicationObjectSupport.java:112) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.context.support.WebApplicationObjectSupport.getServletContext(WebApplicationObjectSupport.java:128) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.initContentNegotiationStrategy(ResourceHttpRequestHandler.java:306) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.afterPropertiesSet(ResourceHttpRequestHandler.java:268) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry.getHandlerMapping(ResourceHandlerRegistry.java:147) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    ... 35 common frames omitted

AutoConfiguration.java

@Configuration
//@EnableAutoConfiguration
@ConditionalOnClass(MyClass.class)
@EnableConfigurationProperties(MyProperties.class)
@ComponentScan({ "com.boot", "com.jspClient" })
@SpringBootApplication
public class AutoConfiguration {

    private static Log log = LogFactory.getLog(AutoConfiguration.class);




    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }

    /*@Bean  
    public UrlBasedViewResolver urlBasedViewResolver() {  
      UrlBasedViewResolver resolver = new UrlBasedViewResolver();  
      resolver.setPrefix("/WEB-INF/jsp/");  
      resolver.setSuffix(".jsp");
      resolver.setViewClass(JstlView.class);  
      return resolver;  
    }*/


    //http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/simple-mapping-exception-resolver/
    //https://github.com/paulc4/mvc-exceptions/blob/master/src/main/java/demo/config/ExceptionConfiguration.java
    @Bean
    public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
      SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
      Properties errorMaps = new Properties();
      errorMaps.setProperty(UserNotFoundException.class.getName(), "myError");
      errorMaps.setProperty("Exception", "generic_error");
      resolver.setExceptionMappings(errorMaps);
      resolver.setDefaultErrorView("generic_error");
      resolver.setExceptionAttribute("exc");
      return resolver;
   }

    @Bean
    WebMvcConfigurer configurer () {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addResourceHandlers (ResourceHandlerRegistry registry) {
                ResourceHandlerRegistration resourceRegistration  = registry
                        .addResourceHandler("/pages/**")
                        .addResourceLocations("/resources/","classpath:/images/")  //Configuring Multiple Locations for a Resource
                        .setCachePeriod(3600);            //The resources served will be cached in the browser for 3600 seconds
                registry.addResourceHandler("resources/**").addResourceLocations("/resources/");
                //registry.addResourceHandler("/css/**").addResourceLocations("/css/");
                //registry.addResourceHandler("/img/**").addResourceLocations("/img/");
                //registry.addResourceHandler("/js/**").addResourceLocations("/js/");
            }
        };
    }
}

AppConfig.java

@Configuration 
@ComponentScan("com.boot.controllers") 
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {  

    @Bean
    public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
      SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
      Properties errorMaps = new Properties();
      errorMaps.setProperty("ElectricityNotFoundException", "error");
      errorMaps.setProperty("NullPointerException", "error");
      resolver.setExceptionMappings(errorMaps);
      resolver.setDefaultErrorView("globalerror");
      resolver.setExceptionAttribute("exc");
      return resolver;
   }
}

WebAppInitializer.java

public class WebAppInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext servletContext) throws ServletException {  
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();  
        ctx.register(AppConfig.class);  
        ctx.setServletContext(servletContext);    
        Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));  
        dynamic.addMapping("/");  
        dynamic.setLoadOnStartup(1);  
   }  
} 

ClientMain.java

@ComponentScan("com.boot") // to scan controller under com.boot -> com.boot.controllers
@SpringBootApplication
public class ClientMain {

    private static SpringApplicationBuilder start(Class<?>... sources) {
        return new SpringApplicationBuilder(ClientMain.class)
            .child(sources);
    }

    public static void main(String[] args) throws Exception {

        // using just Spring alone
        /*ApplicationContext context = new AnnotationConfigApplicationContext(AutoConfiguration.class);

    }

}

JspClientMain.java

@ComponentScan("com.boot") 
@SpringBootApplication
public class JspClientMain {

    public static void main(String[] args) {
        SpringApplication.run(JspClientMain.class, args);
    }
}

2 个答案:

答案 0 :(得分:1)

通常, @EnableWebMvc不应在Spring启动应用程序中使用。我引用article by Boz Hogan

  

事实证明,Spring Boot与标准的Spring MVC @EnableWebMvc不能很好地融合。添加注释时会发生的情况是Spring Boot的自动配置被禁用。

     

糟糕的部分(这让我浪费了几个小时)就是在没有指南的情况下你可以找到明确说明的内容。 (...)

以下是Spring Boot documentation

的引用
  

如果您想保留Spring Boot MVC功能并且想要添加其他MVC配置(拦截器,格式化程序,视图控制器和其他功能),您可以添加自己的@ConfigurationWebMvcConfigurer类但没有 @EnableWebMvc。 (...)

     

如果您想完全控制Spring MVC,可以使用@Configuration添加自己的@EnableWebMvc注释。

所以,要在Spring Boot应用程序中使用@EnableWebMvc,你需要对Spring MVC进行完全控制 - 我读到你需要成为一个Spring wiz < / em>的。

我们遇到了一个Spring Boot 1.5.9应用程序的问题,该应用程序依赖于包含用@EnableWebMvc注释的类的共享库。删除注释解决了问题。

答案 1 :(得分:0)

似乎这个问题是由两种不同类型的初始化器混合引起的,即WebApplicationInitializer和ApplicationContextInitializer。

WebApplicationInitializer和ApplicationContextInitializer都有完全不同的用途。 Servlet容器在启动Web应用程序时使用 WebApplicationInitializer ,并提供了一种编程创建Web应用程序的方法(替换web.xml文件),

ApplicationContextInitializer 提供了一个钩子,用于在完全创建Spring应用程序上下文之前对其进行配置。 对于非Spring启动应用程序/普通spring mvc应用程序,它是web.xml的编程配置。就像你在WebAppInitializer.java中的代码中所做的那样

public class WebAppInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext servletContext) throws 
     ServletException {  
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); 

            ctx.register(AppConfig.class);  
        ctx.setServletContext(servletContext);    
        Dynamic dynamic = servletContext.addServlet("dispatcher", new 
            DispatcherServlet(ctx));  
        dynamic.addMapping("/");  
        dynamic.setLoadOnStartup(1);  
   }  
}

ApplicationContextInitializer 本质上是在完全创建Spring应用程序上下文之前执行的代码。使用ApplicationContextInitializer的一个很好的用例是以编程方式设置Spring环境配置文件。

对于基于Spring-Boot的应用程序,然后注册ApplicationContextInitializer可以像下面这样完成:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleWebApplication {

 public static void main(String[] args) {
  new SpringApplicationBuilder(SampleWebApplication.class)
    .initializers(new DemoApplicationContextInitializer())
    .run(args);
 }
}

public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

 @Override
 public void initialize(ConfigurableApplicationContext ac) {
  ConfigurableEnvironment appEnvironment = ac.getEnvironment();
  appEnvironment.addActiveProfile("demo");

 }
}