【问题标题】:Setting Tomcat Pool properties dynamically动态设置 Tomcat 池属性
【发布时间】:2026-01-15 09:35:01
【问题描述】:

我们有一个包含多个数据源的多租户应用程序,并希望为每个数据源单独配置数据池属性(maxActive、minIdle 等)。

目前我正在构建一个org.apache.tomcat.jdbc.pool.DataSource 并手动设置一些属性,例如使用dataSource.setUserName()dataSource.setPassword() 的用户名和密码。我想通过从字符串加载配置来设置其余属性,例如minIdle=20;initialSize=15

DataSource 上有两种方法似乎可以完成此任务,但似乎并没有按照我的预期进行。我尝试了dataSource.setConnectionProperties("..") 的一些属性以及填充Properties 对象并将其传递给dataSource.setDbProperties(),尽管当我通过JMX 查看池属性时似乎都没有效果。我只能通过特定的设置器(例如dataSource.setInitialSize())来更改这些属性。

我能想到的在没有上述尝试的情况下从它们的字符串中设置每个属性的唯一方法是遍历每个属性并使用 if-else 或 switch-case 逻辑来确定哪个数据源调用设置器来设置值。

那么有没有办法在不调用每个单独的 setter 的情况下从字符串中动态设置这些属性?

当我设置setConnectionPropertiessetDbProperties 的用户名时,它确实发生了变化,但我认为这可能是特定于用户名和密码之类的东西,因为我尝试设置的其他属性没有效果.

编辑:澄清一下,数据源属性将从数据库中加载,并且可能会即时添加新数据源,因此使用应用程序属性将不起作用。

【问题讨论】:

    标签: spring tomcat spring-boot datasource


    【解决方案1】:

    我假设您正在从事 spring-boot 项目。在这种情况下,

    在spring-boot的application.properties文件中创建属性

    spring.datasource.username=XXX
    spring.datasource.password=XXX
    spring.datasource.max-active=XXX
    spring.datasource.min-idle=XXX
    

    并创建配置文件以创建数据源,如下所示

    @Configuration
    public class DataSourceConfiguration {
    
        @Value("${spring.datasource.url}")
        private String url;
        @Value("${spring.datasource.driverClassName}")
        private String driverClass;
        @Value("${spring.datasource.username}")
        private String username;
        @Value("${spring.datasource.password}")
        private String password;
        @Value("${spring.datasource.min-idle}")
        private Long minIdle;
    
        @Bean
        @Primary
        public DataSource dataSource() {
            DataSource dataSource = new DataSource();
            dataSource.setJdbcUrl(url);
            dataSource.setDriverClassName(driverClass);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setMinimumIdle(minIdle);
            return dataSource;
        }
    }
    

    这样,您可以创建多个不同名称的属性,并在创建不同的数据源 Bean 时引用它。

    如果需要,您可以将 application.properties 文件放在项目之外,并在主类中使用 @PropertySource 注释访问它。

    【讨论】:

      【解决方案2】:

      我会使用 Spring Boot ConfigurationProperties 支持。来自手册:

      74.2 配置两个数据源 创建多个数据源的工作方式与创建第一个数据源相同。如果您使用 JDBC 或 JPA 的默认自动配置,您可能希望将其中一个标记为 @Primary(然后任何@Autowired 注入都会选择该配置)。

      @Bean
      @Primary
      @ConfigurationProperties(prefix="datasource.primary")
      public DataSource primaryDataSource() {
          return DataSourceBuilder.create().build();
      }
      
      @Bean
      @ConfigurationProperties(prefix="datasource.secondary")
      public DataSource secondaryDataSource() {
          return DataSourceBuilder.create().build();
      }
      

      如果您担心属性文件中有大量类似的属性,Spring 配置服务器(允许在 GIT 中设置和版本控制)可能会有所帮助。

      【讨论】: