Configuring a Tomcat Connection Pool in Spring Boot – 在Spring Boot中配置Tomcat连接池

最后修改: 2018年 9月 1日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Spring Boot is an opinionated – yet powerful – layer of abstraction placed on top of a plain Spring platform, which makes developing stand-alone and web applications a no-brainer. Spring Boot provides a few handy “starter” dependencies, aimed at running and testing Java applications with a minimal footprint.

Spring Boot是放置在普通Spring平台之上的一个有主见但功能强大的抽象层,它使开发独立的和Web应用程序变得不费力气。Spring Boot提供了一些方便的 “启动器 “依赖,旨在以最小的占用空间来运行和测试Java应用程序。

One key component of these starter dependencies is spring-boot-starter-data-jpa. This allows us to use JPA and work with production databases by using some popular JDBC connection pooling implementations, such as HikariCP and Tomcat JDBC Connection Pool.

这些启动器依赖的一个关键组件是spring-boot-starter-data-jpa/strong>。这使我们能够使用JPA,并通过使用一些流行的JDBC连接池实现来与生产数据库合作,例如HikariCPTomcat JDBC Connection Pool

In this tutorial, we’ll learn how to configure a Tomcat connection pool in Spring Boot.

在本教程中,我们将学习如何在Spring Boot中配置Tomcat连接池

2. The Maven Dependencies

2.Maven的依赖性

Spring Boot uses HikariCP as the default connection pool, due to its remarkable performance and enterprise-ready features.

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

Here’s how Spring Boot automatically configures a connection pool datasource:

以下是Spring Boot如何自动配置连接池数据源:

  1. Spring Boot will look for HikariCP on the classpath and use it by default when present
  2. If HikariCP is not found on the classpath, then Spring Boot will pick up the Tomcat JDBC Connection Pool, if it’s available
  3. If neither of these options is available, Spring Boot will choose Apache Commons DBCP2, if that is available

To configure a Tomcat JDBC connection pool instead of the default HikariCP, we’ll exclude HikariCP from the spring-boot-starter-data-jpa dependency and add the tomcat-jdbc Maven dependency to our pom.xml:

为了配置Tomcat JDBC连接池而不是默认的HikariCP,我们将spring-boot-starter-data-jpa依赖中排除HikariCP,并将tomcat-jdbcMaven依赖到我们的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>

This simple approach allows us to get Spring Boot using a Tomcat connection pool without having to write a @Configuration class and programmatically define a DataSource bean.

这种简单的方法使我们能够使用Tomcat连接池获得Spring Boot,而不必编写@Configuration类,并以编程方式定义DataSourceBean。

It’s also worth noting that in this case, we’re using the H2 in-memory database. Spring Boot will autoconfigure H2 for us, without having to specify a database URL, user, and password.

还值得注意的是,在这种情况下,我们使用的是H2内存数据库Spring Boot将为我们自动配置H2,无需指定数据库URL、用户和密码

We just need to include the corresponding dependency in the “pom.xml” file and Spring Boot will do the rest for us.

我们只需要在“pom.xml”文件中包含相应的依赖关系,Spring Boot将为我们做剩下的事情。

Alternatively, it’s possible to skip the connection pool scanning algorithm that Spring Boot uses and explicitly specify a connection pooling datasource in the “application.properties” file, using the “spring.datasource.type” property:

另外,可以跳过Spring Boot使用的连接池扫描算法,在“application.properties “文件中明确指定一个连接池数据源,使用“spring.datasource.type”/em>属性。

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

3. Tweaking the Connection Pool With the “application.properties” File

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

Once we’ve successfully configured a Tomcat connection pool in Spring Boot, it’s very likely that we’ll want to set up some additional properties, for optimizing its performance and suiting some specific requirements.

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

We can do so in the “application.properties” file:

我们可以在“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   

Please notice that we’ve configured a few additional connection pooling properties, such as the pool’s initial size, and the maximum and minimum number of idle connections.

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

We can also specify some Hibernate-specific properties:

我们还可以指定一些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. Testing the Connection Pool

4.测试连接池

Let’s write a simple integration test to check that Spring Boot has correctly configured the connection pool:

让我们写一个简单的集成测试,检查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. A Sample Command Line Application

5.一个命令行应用程序样本

With all the connection pooling plumbing already set, let’s build a simple command line application.

在所有的连接池设置完成后,让我们建立一个简单的命令行应用程序。

In doing so, we can see how to perform some CRUD operations on an H2 database using the powerful DAO layer that Spring Data JPA (and transitively, Spring Boot) provides out of the box.

在此过程中,我们可以看到如何使用DAO层对H2数据库进行一些CRUD操作,Spring Data JPA(以及Spring Boot)开箱即提供的强大功能。

For a detailed guide on how to get started using Spring Data JPA, please check this article.

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

5.1. The Customer Entity Class

5.1.客户实体类

Let’s first define a naive Customer entity class:

让我们首先定义一个天真的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. The CustomerRepository Interface

5.2.客户库接口

In this case, we just want to perform CRUD operations on a few Customer entities. Additionally, we need to fetch all the customers that match a given last name.

在这种情况下,我们只想对一些Customer实体进行CRUD操作此外,我们需要获取所有与给定姓氏相匹配的客户。

So, all that we have to do is to extend Spring Data JPA’s CrudRepository interface and define a tailored method:

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

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

Now we can easily fetch a Customer entity by its last name.

现在我们可以很容易地通过姓氏来获取一个Customer实体。

5.3. The CommandLineRunner Implementation

5.3.CommandLineRunner实现

Finally, we need at least to persist a few Customer entities in the database and verify that our Tomcat connection pool is actually working.

最后,我们至少需要在数据库中持久化一些Customer实体,并验证我们的Tomcat连接池确实在工作

Let’s create an implementation of Spring Boot’s CommandLineRunner interface. Spring Boot will bootstrap the implementation before launching the application:

让我们创建一个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());
        });
    }
}

In a nutshell, the CommandLineCrudRunner class first saves a couple of Customer entities in the database. Next, it fetches the first one using the findById() method. Finally, it retrieves a customer with the findByLastName() method.

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

5.4. Running the Spring Boot Application

5.4.运行Spring Boot应用程序

Of course, the last thing that we need to do is just run the sample application. Then we can see the Spring Boot/Tomcat connection pool tandem in action:

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

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

6. Conclusion

6.结论

In this tutorial, we learned how to configure and use a Tomcat connection pool in Spring Boot. In addition, we developed a basic command line application to show how easy is to work with Spring Boot, a Tomcat connection pool, and the H2 database.

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

As usual, all the code samples shown in this tutorial are available over on GitHub.

像往常一样,本教程中显示的所有代码样本都可以在GitHub上获得