如何在独立的(war)和嵌入式Tomcat中为Spring Boot应用程序配置数据源?

3

我有一个Spring-Boot应用程序,其dependencyManagement如下:

<dependencyManagement>
  <dependencies>
    <dependency>
      <!-- Import dependency management from Spring Boot -->
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.1.5.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

以及以下依赖关系

spring-boot-starter-jersey
spring-boot-starter-jdbc(exclusion:tomcat-jdbc) 
HikariCP(version:3.3.1)
ojdbc7

我在 Tomcat 上配置了一个JNDI数据源如下:

<Resource name="jdbc/myDS" 
  type="javax.sql.DataSource" 
  driverClassName="oracle.jdbc.driver.OracleDriver" 
  username="Superuser" 
  password="secret"
  url="jdbc:oracle:thin:@xxxDbX"      
  ../>

.properties 文件中,我添加了以下属性:
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource    
spring.datasource.jndi-name=jdbc/myDS

作为Spring-Boot,它能够从属性中配置一个DataSource,我让它这样做,并且不需要编写任何额外的DataSource代码。在独立的Tomcat中部署,它工作得非常完美。
从逻辑上讲,Spring Boot无法在嵌入式Tomcat中找到JNDI资源,并且在将应用作为Spring-Boot-Application启动时,我收到了以下错误提示:
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to bind properties under 'spring.datasource.type' to java.lang.Class<javax.sql.DataSource>:

    Property: spring.datasource.type
    Value: org.apache.tomcat.jdbc.pool.DataSource
    Origin: class path resource [application.properties]:12:24
    Reason: No converter found capable of converting from type [java.lang.String] to type [java.lang.Class<javax.sql.DataSource>]

Action:

Update your application's configuration

我希望能够启动应用程序作为 Spring-Boot-Application 并构建一个 war 文件,该文件可以部署在任何独立的 Tomcat 中。

如果要将应用程序作为 Spring-Boot-Application 启动,同时构建一个 war 文件部署到独立的 Tomcat 中,是否可以通过添加第二个数据源的 properties 来实现?还是我必须拥有第二个 .properties 文件?


正如我所写的:在独立的Tomcat中部署它完美运行。我在“独立的Tomcat”中使用JNDI资源只是因为我必须这样做。对于“嵌入式Tomcat”,我不想使用JNDI:我只想能够将应用程序作为“Spring-Boot-Application”启动,而无需编写数据源。 - Meziane
1
我忘了说谢谢。 谢谢daniel-tung - Meziane
是的,这就是我的问题:我正在尝试找到一个聪明的解决方案,避免为嵌入式Tomcat编写数据源代码。也许可以在.properties文件中添加一些属性,以便Spring-Boot可以像为独立的Tomcat做的那样,使用这些属性自动配置数据源,用于嵌入式Tomcat。 - Meziane
我不相信你可以仅使用属性文件来配置嵌入式Tomcat的JNDI数据源。通过创建我建议的bean,该过程将不会为嵌入式Tomcat运行。这意味着如果数据源更改,您需要编译和部署该项目,但通常如果您更改了属性文件,则也会执行相同操作,尽管在技术上您可以修改它并重新启动应用程序而无需部署。 - Daniel Tung
@daniel-tung:再次强调,我不想在“嵌入式Tomcat”中使用JNDI。 - Meziane
显示剩余2条评论
1个回答

1
我所使用的解决方案是添加一个自定义属性以供嵌入式Tomcat服务器中的数据源使用,示例如下:
# for a dedicated Tomcat
spring.datasource.jndi-name=jdbc/dirserver


# for the embedded Tomcat

embedded.datasource.driver-class-name=oracle.jdbc.OracleDriver
embedded.datasource.url=jdbc:oracle:thin:@//myServer:1521/xxxxx
embedded.datasource.username=superuser
embedded.datasource.password=topsecret

同时,在使用@SpringBootApplication注解的类中定义@Bean DataSource

@SpringBootApplication
public class MySbApplication extends SpringBootServletInitializer {

  private static final Logger lg = LoggerFactory.getLogger(MySbApplication.class);

  @Value("${embedded.datasource.username}")
  String username;
  @Value("${embedded.datasource.password}")
  String password;
  @Value("${embedded.datasource.driver-class-name}")
  String driverClassName;
  @Value("${embedded.datasource.url}")
  String url;

  @Bean(destroyMethod = "")
  public DataSource oracledataSoutŕce() throws SQLException {
    final OracleDataSource dataSource = new OracleDataSource();
    dataSource.setUser(username);
    dataSource.setPassword(password);
    dataSource.setURL(url);
    dataSource.setImplicitCachingEnabled(true);
    dataSource.setFastConnectionFailoverEnabled(true);
    return dataSource;
  }
}

我将在Github上添加一个示例项目链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接