【SFA官方翻译】Spring Boot中配置Tomcat连接池
原文链接:https://www.baeldung.com/spring-boot-tomcat-connection-pool
作者:baeldung
译者:康仔
1. 简介
Spring Boot是在Spring平台基础上开发的固定且功能强大的抽象层,它使得我们的开发独立,且开发web应用程序成为一件无需动脑筋的事情。Spring Boot提供了一些方便的“启动程序”依赖项,旨在以最小的占用空间运行和测试Java应用程序。
这些启动依赖中一个关键组件是 spring-boot-starter-data-jpa。它允许我们使用JPA并通过使用一些流行的JDBC连接池实现(如HikariCP和Tomcat JDBC连接池)连接数据库。
2. Maven依赖
Spring Boot使用了HikariCP作为默认连接池,这是由于其出色的性能和企业特性。
下面是如何用Spring Boot自动配置连接池数据源:
1.Spring Boot将在classpath上查找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注解类并以编程方式定义数据源 的实体。
同样值得注意的是,在本例中,我们使用H2作为内存数据库。 Spring Boot将为我们自动配置H2,而无需指定数据库URL、用户和密码。
我们只需要在“pom.xml”文件中包含相应的依赖关系,Spring Boot将为我们完成其余的工作。
另外,它还可能跳过Spring Boot的连接池扫描算法, 并在“application.properties”文件中使用“spring.datasource.type”属性 显式指定连接池数据源:
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实体类
让我们首先定义一个简单的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操作。此外,我们需要获取匹配给定姓氏的所有客户。
因此,我们所要做的就是扩展Spring Data JPA的CrudRepository接口,并定义一个定制的方法:
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
现在,我们可以很轻松地通过姓氏获取客户实体。
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上找到。