连接到数据库 Spring 启动时出错

Error connecting to database Spring boot

Helo 我一直在尝试使用 Spring 引导连接到数据库一段时间,但我一直收到错误消息:

java.sql.SQLException: url不能为空

我不确定我做错了什么。我试图获得这样的配置的原因是因为我想对数据库使用编码密码。

这是我的文件的样子:

DataConfig.java

@Configuration
public class DataConfig {

    @Autowired
    private Environment env;

    @Configuration
    @Profile(value = "dev")
    public class DevPlaceHolderConfig {

        @Bean
        DataSource dataSource() {

            return DataSourceBuilder
                    .create()
                    .username(env.getProperty("spring.datasource.username"))
                    .password(env.getProperty("spring.datasource.password"))
                    .url(env.getProperty("spring.datasource.url"))
                    .driverClassName(env.getProperty("spring.datasource.driver-class-name"))
                    .build();
        }
    }

    @Configuration
    @Profile(value = "prod")
    public class ProdPlaceHolderConfig {
        @Bean
        DataSource dataSource() {

            return DataSourceBuilder
                    .create()
                    .username(env.getProperty("spring.datasource.username"))
                    .password(env.getProperty("spring.datasource.password"))
                    .url(env.getProperty("spring.datasource.url"))
                    .driverClassName(env.getProperty("spring.datasource.driver-class-name"))
                    .build();
        }
    }
}

EncryptorConfig.java

@Configuration
public class EncryptorConfig {

    @Bean
    public EnvironmentStringPBEConfig environmentVariablesConfiguration() {
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setPasswordEnvName("APP_ENCRYPTION_PASSWORD");
        return config;
    }

    @Bean
    public PooledPBEStringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(environmentVariablesConfiguration());
        return encryptor;
    }
}

application.yml

spring:
  profiles:
    active: prod
  output:
    ansi:
      enabled: always
---
spring:
  profiles: dev
  application:
    name: App-Dev
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 8080

---

spring:
  profiles: prod
  application:
    name: App-Prod
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 3000

这是堆栈跟踪

2017-09-04 09:20:02.476  INFO 18128 --- [           main] com.vir.VirBackendApplication            : The following profiles are active: prod
2017-09-04 09:20:02.536  INFO 18128 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1ebd319f: startup date [Mon Sep 04 09:20:02 EDT 2017]; root of context hierarchy
2017-09-04 09:20:03.479  INFO 18128 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.DataConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/DataConfig$ProdPlaceHolderConfig.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.EncryptorConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/EncryptorConfig$ProdPlaceHolderConfig.class]]
2017-09-04 09:20:03.898  INFO 18128 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-09-04 09:20:04.112  INFO 18128 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$ffc8cc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-09-04 09:20:04.421  INFO 18128 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 5000 (http)
2017-09-04 09:20:04.431  INFO 18128 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2017-09-04 09:20:04.432  INFO 18128 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.16
2017-09-04 09:20:04.589  INFO 18128 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-09-04 09:20:04.589  INFO 18128 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2055 ms
2017-09-04 09:20:04.764  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-04 09:20:04.769  INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-04 09:20:04.817  INFO 18128 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2017-09-04 09:20:04.820  INFO 18128 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2017-09-04 09:20:04.821  INFO 18128 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2017-09-04 09:20:04.967  WARN 18128 --- [           main] o.a.tomcat.jdbc.pool.PooledConnection    : Not loading a JDBC driver as driverClassName property is null.
2017-09-04 09:20:04.978 ERROR 18128 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.

java.sql.SQLException: The url cannot be null
    at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
    at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308) ~[tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.16.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.16.jar:na]
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:326) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:139) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:105) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.CGLIB$jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec$$FastClassBySpringCGLIB$d2e4b4f.invoke(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]

好的,这花了我一段时间,但这就是我解决问题的方法;结果是几个。

  1. 确保在配置中包含 属性 占位符,以便可以绑定实际的 属性 值。 请务必在此处阅读相关内容 enter link description here

所以现在我的 application.yml 文件如下所示,并且 APP_ENCRYPTION_PASSWORD 是一个环境变量,其中包含加密密码。

spring:
  profiles:
    active: prod
  output:
    ansi:
      enabled: detect
---
spring:
  profiles: dev
  application:
    name: App-Dev
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
server:
  port: 8080

---

spring:
  profiles: prod
  application:
    name: App-Prod
  datasource:
    url: jdbc:mysql://localhost:3306/database?useSSL=false
    username: root
    password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
    driver-class-name: com.mysql.jdbc.Driver 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: ${APP_ENCRYPTION_PASSWORD}
server:
  port: 3000
  1. 只需要一个数据源配置bean。我将其设置为更改活动配置文件,以便选择正确的配置。

同时创建私有变量并使用 @Value() 注释绑定它们。还将 @EnableEncryptableProperties 添加到 class.

DataConfig.java

@Configuration
@EnableEncryptableProperties
public class DataConfig {

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;


    @Bean
    DataSource dataSource() {
        return DataSourceBuilder
                .create()
                .username(userName)
                .password(password)
                .url(url)
                .driverClassName(driverClassName)
                .build();
    }
}

就是这样,它解决了我所有的问题。