1. 概述
Spring Boot 是一個在純粹的 Spring 平台上放置的、帶有觀點但又強大的抽象層,它使得獨立應用程序和 Web 應用程序的開發變得輕而易舉。Spring Boot 提供了一些方便的“starter”依賴項,旨在使用最小的足跡運行和測試 Java 應用程序。
這些 starter 依賴項的關鍵組件是 spring-boot-starter-data-jpa。 這樣,我們就可以使用 JPA 並使用流行的 JDBC 連接池實現,如 HikariCP 和 Tomcat JDBC Connection Pool。
在本教程中,我們將學習如何配置 Spring Boot 中的 Tomcat 連接池。
2. Maven 依賴項
Spring Boot 使用 HikariCP 作為默認連接池,因為它具有卓越的性能和企業級特性。以下是如何 Spring Boot 自動配置連接池數據源的方式:
- Spring Boot 會在類路徑上查找 HikariCP 並默認使用它,如果存在的話
- 如果類路徑上未找到 HikariCP,則 Spring Boot 會選擇 Tomcat JDBC 連接池,如果可用
- 如果以上兩種選項均不可用,Spring Boot 將選擇 Apache Commons DBCP2,如果該選項可用
要配置 Tomcat JDBC 連接池而不是默認的 HikariCP,我們將 排除 HikariCP 從 spring-boot-starter-data-jpa 依賴項,並添加 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>10.1.7</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<scope>runtime</scope>
</dependency>這種簡單方法允許我們使用 Tomcat 連接池獲取 Spring Boot,而無需編寫 @Configuration 類和通過編程方式定義 DataSource Bean。
此外,在本例中,我們使用了 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 properties3. 通過“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. 客户實體類
讓我們首先定義一個簡單的 客户實體類:
@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 接口並定義一個定製的方法:</em translate="no">
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}現在我們可以輕鬆地通過姓氏獲取 Customer 實體。
5.3. CommandLineRunner 實現
最後,我們需要至少在數據庫中持久化幾個 <em>Customer</em> 實體,並 驗證我們的 Tomcat 連接池是否實際工作。
讓我們創建一個 Spring Boot 的 <em>CommandLineRunner</em> 接口的實現。 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 數據庫的便捷性。