Spring异常分析

异常报错


2019-01-14 10:40:18.427 ERROR 11776 --- [ost-startStop-1] o.s.b.w.e.t.TomcatStarter                : Error starting Tomcat context. 

Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'servletEndpointRegistrar' defined in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration$WebMvcServletEndpointManagementContextConfiguration.class]: 


Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 

Failed to instantiate [org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar]: 


Factory method 'servletEndpointRegistrar' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException:



 Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthEndpoint]: Factory method 'healthEndpoint' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: 


 Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration':
  Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: 


  Failed to instantiate [org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration$$EnhancerBySpringCGLIB$$caa88ea6]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: 

  Error creating bean with name 'dataSource': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: 

  Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

关键在最后一句Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

我这里是有配置mysql驱动的。所以定位应该是配置问题。

根据提示,可以看出是从DataSourceProperties这里抛出来的异常。读取spring.datasource开头的配置项。如果spring.datasource.driverClassName为空,会抛出异常,提示Failed to determine a suitable driver class

我的配置文件里是有配置的,该配置在读取时会将driver-class-name转换为驼峰式写法driverClassName。所以问题应该是Springboot没有加载application.properties的问题,可以来验证一下。

Spring异常分析

Spring异常分析

启动后,异常信息变成

Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine suitable jdbc url

spring.datasource.driver-class-name=com.mysql.jdbc.Driver


@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {


        public String determineDriverClassName() {
        if (StringUtils.hasText(this.driverClassName)) {
            Assert.state(driverClassIsLoadable(),
                    () -> "Cannot load driver class: " + this.driverClassName);
            return this.driverClassName;
        }
        String driverClassName = null;
        if (StringUtils.hasText(this.url)) {
            driverClassName = DatabaseDriver.fromJdbcUrl(this.url).getDriverClassName();
        }
        if (!StringUtils.hasText(driverClassName)) {
            driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
        }
        if (!StringUtils.hasText(driverClassName)) {
            throw new DataSourceBeanCreationException(
                    "Failed to determine a suitable driver class", this,
                    this.embeddedDatabaseConnection);
        }
        return driverClassName;
    }


}

测试加载的配置文件



public class KzfApiAlipayApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(KzfApiAlipayApplication.class, args);
        System.out.println(context.getEnvironment().getProperty("spring.datasource.driver-class-name"));
    }

}


public class ServletEndpointManagementContextConfiguration {

        @Configuration
    @ConditionalOnClass(DispatcherServlet.class)
    public static class WebMvcServletEndpointManagementContextConfiguration {

        private final ApplicationContext context;

        public WebMvcServletEndpointManagementContextConfiguration(
                ApplicationContext context) {
            this.context = context;
        }

        @Bean
        public ServletEndpointRegistrar servletEndpointRegistrar(
                WebEndpointProperties properties,
                ServletEndpointsSupplier servletEndpointsSupplier) {
            DispatcherServletPath dispatcherServletPath = this.context
                    .getBean(DispatcherServletPath.class);
            return new ServletEndpointRegistrar(
                    dispatcherServletPath.getRelativePath(properties.getBasePath()),
                    servletEndpointsSupplier.getEndpoints());
        }

    }

}

SpringBoot启动过程


@SpringBootApplication
public class CrawlerDiscreditApplication {

    public static void main(String[] args) {

        SpringApplication.run(CrawlerDiscreditApplication.class, args);

    }

}

SpringApplication类


public class SpringApplication {

        private ResourceLoader resourceLoader;

        public SpringApplication(Class<?>... primarySources) {
        this(null, primarySources);
    }

        public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        this.webApplicationType = deduceWebApplicationType();
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }

    
        

}


上一篇:python – 从不等长度的嵌套列表创建一个pandas数据帧


下一篇:PHP simpleXML如何检查嵌套子项是否存在