Overview

A datasource in Spring Boot is a mechanism for providing database connectivity to the application.
The purpose of using a datasource in Spring Boot is to provide a convenient and consistent way to interact with databases in the application.
It eliminates the need for the application to manage database connections directly, and provides a common interface for accessing databases, regardless of the underlying database technology.
In this article, we will cover different ways in which you can configure a datasource in a spring boot application.

1. Using application.properties file
If you add spring provided or pre-defined properties related to database connection in application.properties or application.yml file, spring boot will automatically create a datasource. Example,

# application.properties
spring.datasource.url=jdbc:mysql://localhost/appdb
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost/mydb
    username: user
    password: password
    driver-class-name: com.mysql.jdbc.Driver

Remember that default location of these files in a spring boot project is inside src/main/resources folder

2. Using DataSourceBuilder
org.springframework.boot.jdbcDataSourceBuilder is a utility or convenience class in spring boot that provides a convenient way to create and configure a datasource.
Using this class, we can create a datasource in using connection parameters, such as database URL, username, and password.

Once DataSourceBuilder is created, we can provide it connection parameters using its methods and then use it to create a datasource as shown below

@Configuration
public class DataSourceConfig {

  @Bean
  public DataSource dataSource() {
    return DataSourceBuilder
      .create()
      .url("jdbc:mysql://localhost/appdb")
      .username("user")
      .password("password")
      .driverClassName("com.mysql.jdbc.Driver")
      .build();
  }
}

Note that we are marking the class with @Configuration annotation, which marks it as source of beans.
And in the configuration class, we expose a bean of type DataSource.

You can also provide connection parameters to DataSourceBuilder from an external properties file using @Value annotation as shown below

@Configuration
public class DataSourceConfig {

  @Value("${spring.datasource.url}")
  private String url;

  @Value("${spring.datasource.username}")
  private String username;

  @Value("${spring.datasource.password}")
  private String password;

  @Bean
  public DataSource dataSource() {
    return DataSourceBuilder
      .create()
      .url(url)
      .username(username)
      .password(password)
      .build();
  }
}

You can also use your own property names instead of spring’s pre-defined property names as below.

@Configuration 
public class DataSourceConfig {
  @Value("${ds.url}")
  private String url;

  @Value("${ds.username}")
  private String username;

  @Value("${ds.password}")
  private String password;

  @Bean 
  public DataSource dataSource() { 
    return DataSourceBuilder.
           create().
           url(url).
           username(username).
           password(password).
           build(); 
  }
}

3. Using custom DataSource
You can also create your own custom datasource by creating a class that implements javax.sql.DataSource interface as shown below

public class CustomDataSource implements DataSource {
  private String url;
  private String username;
  private String password;

  public CustomDataSource(String url, String user, String pwd) {
    this.url = url;
    this.username = user;
    this.password = pwd;
  }

  // implementation of the DataSource interface

  // getters and setters for the connection parameters
  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }
}

@Configuration
public class DataSourceConfig {

  @Value("${spring.datasource.url}")
  private String url;

  @Value("${spring.datasource.username}")
  private String username;

  @Value("${spring.datasource.password}")
  private String password;

  @Bean
  public DataSource dataSource() {
    return new CustomDataSource(url, username, password);
  }
}

Note that your custom data source class should contain all the fields required to establish a database connection.
4. Using JNDI
JNDI, which stands for Java Naming and Directory Interface, is a Java API that provides a naming service for Java objects.
That is, you can look up and access objects using a name, with which it is registered in environment.
A JNDI datasource is a datasource that is registered with a JNDI naming service and is looked up using the JNDI API.

In a JNDI DataSource configuration, you register the datasource with a JNDI service, and then use the JNDI name to look up the datasource in your application code.
This approach is typically useful, when you use external Tomcat to deploy your application instead of embedded server.
You can use JNDI to register a datasource with the application server, and then use the JNDI name to look up the datasource in your application code. Example,

InitialContext initialContext = new InitialContext();
DataSource dataSource = 
          (DataSource) initialContext.lookup(
                          "java:comp/env/jdbc/myDS");

In this example, the DataSource is registered with JNDI under the name java:comp/env/jdbc/myDS and is looked up using the JNDI API.

That is all on various ways to configure datasource in a spring boot application.
You can choose the method that meets the specific requirements of your application.