레벨2 브리의 강의에서 AutoConfiguration이라는 키워드가 나왔습니다.
DataSource도 지하철 미션도 DataSource가 AutoConfiguration으로 등록되기 때문에, breakpoint를 찍어보면서 어떤 과정을 통해서 DataSource가 AutoConfiguration 되는지 직접 알아보았습니다.
많이 부족한 글입니다. 잘못된 정보가 있다면 피드백 부탁드립니다!
참고로, 저는 HikariDataSource가 Bean으로 등록되었으니 참고하면서 읽으시면 좋을 것 같습니다~!
DataSourceAutoConfiguration에서는 환경에 따라, EmbeddeDataSource를 빈으로 등록할 수 있는지, PooledDataSource를 빈으로 등록할 수 있는지 체크합니다. 위의 Conditional에 해당하는 코드를 아래에서 보면
먼저 PooledDataSource를 사용할 수 있는 Condition인지를 체크합니다. 현재 저는 HikariDataSource를 사용할 수 있는 환경이기 때문에, 가능하다는 조건을 반환합니다.
다음으로, Embedded를 체크하는데요. 불가능하다는 조건을 반환합니다. 이유는, 저는 지금 Hikari(PooledDataSource)를 사용할 수 있기 때문입니다. 사진의 젤 위에 있는 명세를 읽어보시면, PooledDataSource가 사용될 수 있다면, Embedded보다 Pooled가 선호된다고 적혀있습니다.
사실 위의 Condition 체크를 어떤식으로 하는지, 어떤 데이터를 불러오는지가 궁금했는데요. 공식 문서를 찾아봐도 설명을 찾을 수가 없었습니다. 주변에 물어봐도, Pooled와 Embbeded를 사용할 수 있는 환경인지를 검사하는 것이라고만 알고 있다는 답변을 받았습니다. 위의 내용에 대해 구체적으로 아시는 분이 있으면 댓글 달아주시면 감사하겠습니다!
그 후에, 저희가 아래에 설정한 yml파일을 읽어들여서 DataSourceProperties라는 객체를 생성합니다.
@EnableConfigurationPreperties
을 통해 저희 작성한 yml 값을 가지는 DataSourceProperties
객체를 생성할 수 있습니다.
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb
username: sa
password:
여기서 저는 ‘url을 인메모리 DB로 설정하였는데, 왜 DataSource는 Hikari가 되는거지?’라는 궁금증이 들었습니다. 그 이유는 DB와 DataSource는 다른 것입니다. 저는 두 개념이 헷갈려서 조금 헤맸는데요. 차이에 대해서 알아보시면 좋을 것 같습니다.
다시 돌아와서,
아래의 DataSourceProperties의 @ConfigurationProperties의 perfix가 위의 yml에서 설정한 값과 같기 때문에, yml 파일의 값에 기반한 DataSourceProperties를 생성할 수 있습니다.
DataSourceProperties에는 아래와 같은 필드들이 있습니다.
package org.springframework.boot.autoconfigure.jdbc;
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
private boolean generateUniqueName = true;
private String name;
private Class<? extends DataSource> type;
private String driverClassName;
private String url;
private String username;
private String password;
private String jndiName;
//모든 필드를 작성한 것이 아니니,
//궁금하신 분들은 직접 DataSourceProperties 객체를 확인해보시면 좋을 것 같습니다.
}
그 후에, DataSourceProperties의 initializeDataSourceBuilder
메서드를 통해 DataSoureceBuilder
객체를 생성합니다. 빈으로 등록하기 위한 DataSource 객체를 생성하는 것은 DataSourceBuilder
입니다.
생성된 DataSourceBuilder의 build() 메서드를 통해서 DataSource 구현체를 생성하여 Bean으로 등록할 수 있습니다.
저는 HikariDataSource가 빈으로 등록되었는데요. 위의 yml에서 DataSource의 타입을 지정해주지 않았는데, HikariDataSource가 AutoConfiguration 되었습니다.
왜일까요?
When no {@link #type(Class) type} has been explicitly set, the first available pool
* implementation will be picked:
* <ul>
* <li>Hikari ({@code com.zaxxer.hikari.HikariDataSource})</li>
* <li>Tomcat JDBC Pool ({@code org.apache.tomcat.jdbc.pool.DataSource})</li>
* <li>Apache DBCP2 ({@code org.apache.commons.dbcp2.BasicDataSource})</li>
* <li>Oracle UCP ({@code oracle.ucp.jdbc.PoolDataSourceImpl})</li>
public final class DataSourceBuilder<T extends DataSource> {
개발자가 DataSource의 type을 직접 지정하지 않으면 DataSourceBuiler가 자동으로 타입을 지정합니다. 자동 지정하는 데에는 위와 같이 Spring에서 지정한 우선 순위가 있는데요. 의존성 주입이 된 타입들 중에, 가장 높은 우선 순위의 type이 자동으로 지정되게 되어있습니다.
저는 spring-boot-starter-jdbc의 의존성이 주입되어있는데, 해당 의존성을 주입하게 되면 Hikari에 대한 의존이 함께 주입되기 때문에, DataSource의 type이 type이 Hikari로 지정되었습니다.
DataSource가 AutoConfiguration 되는과정에 대해서 알아보았습니다. DataSource는 알아갈 수록 재밌는 것 같아요.
킹갓제너럴 리차드
이 DataSource Connection Pool에 있는 Connection들의 유효성을 보장해주기 위해서, DataSource의 옵션을 설정해주어야 하는 것이 있다면서 제 호기심을 자극했는데요. 다음에 꼭 알아보도록 하겠습니다~
끗
👍👍👍