Understanding how Spring Boot automatically creates and manages database connections is very important for Spring Boot developers.
Spring Boot uses Auto Configuration + Connection Pooling + Dependency Injection to create and provide DataSource and Connection objects.
application.properties
│
▼
Spring Boot Auto Configuration
│
▼
Creates DataSource Bean
│
▼
Connection Pool (HikariCP)
│
▼
Connections created and managed
│
▼
Spring injects DataSource into your code
│
▼
You call getConnection()
spring.datasource.url=jdbc:mysql://localhost:3306/employees spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Spring Boot has an internal class:
DataSourceAutoConfiguration
Auto configuration class:
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
| Priority | Connection Pool |
|---|---|
| 1 | HikariCP (default) |
| 2 | Tomcat JDBC |
| 3 | Commons DBCP |
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/employees");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
Normally you do not write this code. Spring Boot generates it automatically.
Connection Pool (HikariCP) +----------------------+ | Connection 1 | | Connection 2 | | Connection 3 | | Connection 4 | | Connection 5 | +----------------------+
@Service
public class EmployeeService {
@Autowired
private DataSource dataSource;
}
Connection connection = dataSource.getConnection();
@Service
public class EmployeeService {
@Autowired
private DataSource dataSource;
public void testConnection() throws Exception {
Connection conn = dataSource.getConnection();
System.out.println(conn);
conn.close();
}
}
Important: conn.close() does NOT close the real connection. It returns the connection to the pool.
Spring Boot Application
│
▼
application.properties
│
▼
DataSourceAutoConfiguration
│
▼
HikariDataSource Bean
│
▼
Hikari Connection Pool
┌──────────────────┐
│ Connection 1 │
│ Connection 2 │
│ Connection 3 │
│ Connection 4 │
│ Connection 5 │
└──────────────────┘
│
▼
Injected into Beans
│
▼
dataSource.getConnection()
│
▼
Database
1 → Request goes to HikariDataSource 2 → Hikari checks pool 3 → Available connection returned 4 → Your application uses it 5 → conn.close() 6 → Returned back to pool
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/employees");
config.setUsername("root");
config.setPassword("root");
HikariDataSource ds = new HikariDataSource(config);
Connection conn = ds.getConnection();
| Component | Class |
|---|---|
| Auto Configuration | DataSourceAutoConfiguration |
| Properties Binding | DataSourceProperties |
| Pool | HikariDataSource |
| Connection | java.sql.Connection |
Controller
│
▼
Service
│
▼
JpaRepository
│
▼
Spring Data JPA
│
▼
EntityManager
│
▼
Hibernate (JPA Provider)
│
▼
DataSource
│
▼
Connection Pool (HikariCP)
│
▼
Database
@Entity
@Table(name="employees")
public class Employee {
@Id
@GeneratedValue
private Long id;
private String name;
}
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository repository;
public Employee save(Employee emp){
return repository.save(emp);
}
}
repository.save(employee)
│
▼
Spring Data JPA Proxy
│
▼
EntityManager.persist()
│
▼
Hibernate
│
▼
DataSource.getConnection()
│
▼
HikariCP Connection Pool
│
▼
Database
Spring Boot Application
│
▼
Spring Data JPA Repository
│
▼
Proxy Implementation
│
▼
EntityManager
│
▼
Hibernate
│
▼
DataSource
│
▼
Hikari Connection Pool
│
▼
Database
| Layer | Class |
|---|---|
| Repository | SimpleJpaRepository |
| JPA API | EntityManager |
| ORM | Hibernate |
| Connection | DataSource |
| Pool | HikariDataSource |
JpaRepository
↓
EntityManager
↓
Hibernate
↓
DataSource
↓
Connection Pool
↓
Database