Spring Boot在以编程方式配置数据源时不会使用spring.datasource.tomcat.*吗?

3

我正在配置两个数据源,并尝试设置池化属性,根据文档,我应该使用spring.datasource.tomcat.*,但似乎与我所做的配置不兼容。我做错了什么?或者我漏掉了什么?

我的application.properties文件:

spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validationQuery=SELECT 1 
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username
spring.datasource.password

spring.read.datasource.tomcat.test-on-borrow=true
spring.read.datasource.tomcat.validationQuery=SELECT 1 
spring.read.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.read.datasource.username
spring.read.datasource.password

以下是我的配置类: 我有一个类似的用于读取数据源(针对不同的 repo/entities)。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager",
basePackages = "com.test.feature.repo.internal")
public class DataSourceConfig {

    @Primary
    @Bean("dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name="entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, 
            @Qualifier("dataSource")DataSource dataSource){
        return builder.dataSource(dataSource).packages("com.test.feature.entity.internal").persistenceUnit("defaultPersistenceUnit").build();
    }

    @Primary
    @Bean(name="transactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory){
        return new JpaTransactionManager(entityManagerFactory);
    }
}

如果我尝试使用spring.datasource.test-on-borrow=true,那么它可以工作。
我真的想知道为什么.tomcat.*样式不起作用?我该怎么做才能让它起作用?
即使有人可以将我引导到一些有用的阅读材料来理解这个问题,我也会很高兴。 :)

你使用的是哪个版本? - Kohei TAMURA
我正在使用1.5.4版本。 - Sachin Sharma
在1.5.7版本中,我也遇到了同样的问题。DataSource无法获取spring.datasource.tomcat.*属性。对我来说,即使是spring.datasource.test-on-borrow=true也无效。 - Nikhil Sahu
1
在这里记录了一个问题:https://github.com/spring-projects/spring-boot/issues/10845 - Nikhil Sahu
4个回答

4
那份文档是关于自动配置的,而你没有使用它。如果你正在编写自定义代码来设置DataSource,那么你也需要负责绑定配置。
你上面的代码有一个@ConfigurationProperties("spring.datasource")。如果你删除它,那么在你自己的代码中就不会考虑任何spring.datasource.*属性。 文档的这一部分解释了基本属性(spring.datasource)和数据源绑定(spring.datasource.xyz.*)之间的区别。
无论如何,如果你正在自己创建DataSource (为什么?),那么请使用一个单独的命名空间。重用spring.datasource命名空间会让用户感到困惑,因为用户期望自动配置提供的功能将被尊重。但是由于你正在编写自己的配置,所以这些功能将不会被尊重。

那么如何配置多个数据源,以确保连接池属性不受影响呢?(在这种情况下是Tomcat JDBC连接池)。文档中没有涵盖这方面的内容。 - Nikhil Sahu
文档正好涵盖了这个问题(我在我的回答中给出了链接)。你看过了吗? - Stephane Nicoll
找到了。我忘记连接属性也可以在同一个命名空间中指定。谢谢你的帮助。 - Nikhil Sahu
我自己创建了两个数据源Bean,因为我想连接一个用于写入数据的数据源和一个用于读取数据的数据源,并基于包名为两者都启用JPA存储库。 - Sachin Sharma
这真的很有帮助!我们将所有微服务都更新到了新的池特定配置,包括一个具有两个数据源的微服务。我们需要使用 *datasource.tomcat.* 来进行自动配置的数据源,而对于手动配置的数据源则不需要池的名称。在引入池特定属性之前,自动配置和手动配置的结构是相同的。然而,我必须承认,从技术角度来看,这绝对是有意义的。 - jaw

1
我已经在我的application.properties文件中添加了以下两行代码。
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.read.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

它正在运行...谢谢。


0
如果您只有一个数据源和自动配置,您只需要使用 spring.datasource.* 进行配置。默认情况下,将选择 tomcatcp 作为连接池。
在您的情况下:如果要以编程方式配置两个数据源,请在您的 application.properties 文件中添加以下注释 spring.datasource.type,以告诉它您选择了哪个连接池。

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource spring.read.datasource.type=org.apache.tomcat.jdbc.pool.DataSource


0
我遇到的问题与你的类似。我试图在外部设置数据源连接,并且我还想利用Spring的自动配置操作。所以我学到的是使用EnvironmentPostProcessor来修改属性,并让Spring使用修改后的属性。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;

import java.util.Properties;
import java.util.UUID;

public class ExternalDataSourceEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        // Get the MutablePropertySources
        MutablePropertySources propertySources = environment.getPropertySources();

        // Remove existing properties
        propertySources.remove("spring.datasource.url");
        propertySources.remove("spring.datasource.username");
        propertySources.remove("spring.datasource.password");

        // Generate random values for properties
        String randomUrl = "jdbc:mysql://" + UUID.randomUUID().toString();
        String randomUsername = "user" + UUID.randomUUID().toString();
        String randomPassword = UUID.randomUUID().toString();

        // Add random properties
        Properties randomProperties = new Properties();
        randomProperties.setProperty("spring.datasource.url", randomUrl);
        randomProperties.setProperty("spring.datasource.username", randomUsername);
        randomProperties.setProperty("spring.datasource.password", randomPassword);

        propertySources.addLast(
            new PropertiesPropertySource("external-datasource", randomProperties)
        );
    }
}

点击这个链接获取更多信息。

https://www.baeldung.com/spring-boot-environmentpostprocessor


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