在Spring Boot中配置Tomcat连接池

2023/05/18

1. 概述

Spring Boot是一个自以为是但功能强大的抽象层,构建于普通Spring平台之上,这使得开发独立应用程序和Web应用程序变得轻而易举。Spring Boot提供了一些方便的“启动器”依赖项,旨在以最小的占用空间运行和测试Java应用程序。

这些启动器依赖项的一个关键组件是spring-boot-starter-data-jpa,这允许我们使用JPA并通过使用一些流行的JDBC连接池实现(例如HikariCPTomcat JDBC连接池)来处理生产数据库。

在本教程中,我们介绍如何在Spring Boot中配置Tomcat连接池

2. Maven依赖

Spring Boot使用HikariCP作为默认连接池,因为它具有卓越的性能和企业级功能。

以下是Spring Boot自动配置连接池数据源的方式

  1. Spring Boot将在类路径中查找HikariCP,并在存在时默认使用它
  2. 如果在类路径中找不到HikariCP,那么Spring Boot将选择Tomcat JDBC连接池(如果可用)
  3. 如果这些选项都不可用,Spring Boot将选择Apache Commons DBCP2(如果可用)

要配置Tomcat JDBC连接池而不是默认的HikariCP,我们将从spring-boot-starter-data-jpa依赖项中排除HikariCP,并将tomcat-jdbc Maven依赖项添加到我们的pom.xml中

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>9.0.10</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.197</version>
    <scope>runtime</scope>
</dependency>

这种简单的方法允许让Spring Boot使用Tomcat连接池,而无需编写@Configuration类并以编程方式定义DataSource bean。

还值得注意的是,在本例中,我们使用的是H2内存数据库。Spring Boot将为我们自动配置H2,而无需指定数据库URL、用户和密码

我们只需要在pom.xml文件中包含相应的依赖项,Spring Boot就会为我们完成剩下的工作。

或者,可以跳过Spring Boot使用的连接池扫描算法,并使用“spring.datasource.type”属性在application.properties文件中显式指定连接池数据源

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
# other spring datasource properties

3. 使用application.properties文件调整连接池

一旦我们在Spring Boot中成功配置了Tomcat连接池,我们很可能需要设置一些额外的属性,以优化其性能并满足某些特定要求

我们可以在application.properties文件中实现这一点:

spring.datasource.tomcat.initial-size=15
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=15
spring.datasource.tomcat.min-idle=8
spring.datasource.tomcat.default-auto-commit=true

请注意,我们配置了一些额外的连接池属性,例如池的初始大小以及空闲连接的最大和最小数量。

我们还可以指定一些Hibernate特定的属性:

# Hibernate specific properties
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.id.new_generator_mappings=false

4. 测试连接池

让我们编写一个简单的集成测试来检查Spring Boot是否正确配置了连接池:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootTomcatConnectionPoolIntegrationTest {

    @Autowired
    private DataSource dataSource;

    @Test
    public void givenTomcatConnectionPoolInstance_whenCheckedPoolClassName_thenCorrect() {
        assertThat(dataSource.getClass().getName()).isEqualTo("org.apache.tomcat.jdbc.pool.DataSource");
    }
}

5. 命令行应用程序示例

设置好所有连接池管道后,我们构建一个简单的命令行应用程序。

在这样做的过程中,我们可以看到如何使用Spring Data JPA(以及传递依赖的Spring Boot)开箱即用的强大DAO层对H2数据库执行一些CRUD操作。

有关如何使用Spring Data JPA的详细指南,请查看这篇文章。

5.1 客户实体类

首先我们定义一个简单的Customer实体类:

@Entity
@Table(name = "customers")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "first_name")
    private String firstName;

    // standard constructors / getters / setters / toString
}

5.2 CustomerRepository接口

在这种情况下,我们只想对几个Customer实体执行CRUD操作。此外,我们需要获取与给定lastName匹配的所有客户。

因此,我们所要做的就是扩展Spring Data JPA的CrudRepository接口并定义一个自定义的方法

public interface CustomerRepository extends CrudRepository<Customer, Long> {
    List<Customer> findByLastName(String lastName);
}

现在我们可以轻松地通过lastName获取Customer实体。

5.3 CommandLineRunner实现

最后,我们至少需要在数据库中持久化一些Customer实体,并验证我们的Tomcat连接池是否实际有效

让我们创建Spring Boot的CommandLineRunner接口的实现,Spring Boot将在启动应用程序之前引导实现:

public class CommandLineCrudRunner implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(CommandLineCrudRunner.class);

    @Autowired
    private final CustomerRepository repository;

    public void run(String... args) throws Exception {
        repository.save(new Customer("John", "Doe"));
        repository.save(new Customer("Jennifer", "Wilson"));

        logger.info("Customers found with findAll():");
        repository.findAll().forEach(c -> logger.info(c.toString()));

        logger.info("Customer found with findById(1L):");
        Customer customer = repository.findById(1L)
              .orElseGet(() -> new Customer("Non-existing customer", ""));
        logger.info(customer.toString());

        logger.info("Customer found with findByLastName('Wilson'):");
        repository.findByLastName("Wilson").forEach(c -> {
            logger.info(c.toString());
        });
    }
}

简而言之,CommandLineCrudRunner类首先在数据库中保存几个Customer实体。接下来,它使用findById()方法获取第一个。最后,它使用findByLastName()方法检索客户。

5.4 运行Spring Boot应用程序

当然,我们需要做的最后一件事就是运行示例应用程序,然后我们可以看到Spring Boot/Tomcat连接池的串联运行:

@SpringBootApplication
public class SpringBootConsoleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsoleApplication.class);
    }
}

6. 总结

在本教程中,我们学习了如何在Spring Boot中配置和使用Tomcat连接池。此外,我们开发了一个基本的命令行应用程序来演示Spring Boot、Tomcat连接池和H2数据库的使用。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章