How Spring Boot Creates DataSource and Connection Objects and Provides Them to Your Application

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.

1. High-Level Flow

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()

2. Step 1 — You Define Database Properties

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

3. Step 2 — Spring Boot Auto Configuration

Spring Boot has an internal class:

DataSourceAutoConfiguration

Auto configuration class:

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

4. Step 3 — Spring Boot Chooses Connection Pool

PriorityConnection Pool
1HikariCP (default)
2Tomcat JDBC
3Commons DBCP

5. Step 4 — DataSource Bean Creation

@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.

6. Step 5 — Connection Pool Creates Connections

Connection Pool (HikariCP)

+----------------------+
| Connection 1         |
| Connection 2         |
| Connection 3         |
| Connection 4         |
| Connection 5         |
+----------------------+

7. Step 6 — Spring Injects DataSource

@Service
public class EmployeeService {

    @Autowired
    private DataSource dataSource;

}

8. Step 7 — Getting Connection Object

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.

9. Internal Working Diagram

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

10. What Happens When getConnection() is Called

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

11. Without Spring Boot (Traditional Java)

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();

12. Important Classes Involved

ComponentClass
Auto ConfigurationDataSourceAutoConfiguration
Properties BindingDataSourceProperties
PoolHikariDataSource
Connectionjava.sql.Connection

13. Key Takeaways


Additional Section: How Connections Work When Using Spring Data JPA (JpaRepository)

1. High-Level Flow with JPA Repository

Controller
    │
    ▼
Service
    │
    ▼
JpaRepository
    │
    ▼
Spring Data JPA
    │
    ▼
EntityManager
    │
    ▼
Hibernate (JPA Provider)
    │
    ▼
DataSource
    │
    ▼
Connection Pool (HikariCP)
    │
    ▼
Database

2. Example Entity

@Entity
@Table(name="employees")
public class Employee {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

}

3. Repository Example

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

}

4. Service Layer

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository repository;

    public Employee save(Employee emp){
        return repository.save(emp);
    }

}

5. What Happens Internally When repository.save() Runs

repository.save(employee)
        │
        ▼
Spring Data JPA Proxy
        │
        ▼
EntityManager.persist()
        │
        ▼
Hibernate
        │
        ▼
DataSource.getConnection()
        │
        ▼
HikariCP Connection Pool
        │
        ▼
Database

6. Internal Working Diagram

Spring Boot Application
        │
        ▼
Spring Data JPA Repository
        │
        ▼
Proxy Implementation
        │
        ▼
EntityManager
        │
        ▼
Hibernate
        │
        ▼
DataSource
        │
        ▼
Hikari Connection Pool
        │
        ▼
Database

7. Important Classes Involved

LayerClass
RepositorySimpleJpaRepository
JPA APIEntityManager
ORMHibernate
ConnectionDataSource
PoolHikariDataSource

8. Key Idea

JpaRepository
     ↓
EntityManager
     ↓
Hibernate
     ↓
DataSource
     ↓
Connection Pool
     ↓
Database