Spring DB : 스프링부트와 자동 리소스 등록

    이 글은 인프런 김영한님의 강의를 복습하며 작성한 글입니다. 

    스프링 부트의 자동 리소스 등록

    스프링 부트가 등장하기 이전에 개발자들은 DataSource와 TransactionManager를 개발자가 직접 스프링 빈으로 등록해서 사용했다. 그런데 스프링 부트로 개발을 시작한 개발자라면 DataSource나 TransactionManager를 직접 등록한 적이 없다. 

     

    레거시 스프링 : DataSource + TransactionManager 직접 등록

    @Bean
    public DataSource dataSource() {
       HikariDataSource dataSource = new HikariDataSource();
       dataSource.setJdbcUrl(URL);
       dataSource.setUsername(USERNAME);
       dataSource.setPassword(PASSWORD);
       return dataSource;
    }
    
    @Bean
    public TransactionManager transactionManager() {
       return new DataSourceTransactionManager(dataSource());
    }
    • 기존에는 개발자가 DataSource /  TranscationManager를 직접 스프링 빈으로 등록해야했다.
    • 스프링 부트는 DataSource / TransactionManager를 스프링 빈으로 등록해준다.

     

    DataSource : 스프링 부트가 자동 등록 

    • 스프링 부트는 DataSource를 스프링 빈으로 자동 등록해준다. 
    • 자동 등록되는 스프링 빈의 이름은 dataSource다. 
    • 개발자가 직접 DataSource를 빈으로 등록하면, 스프링 부트는 DataSource를 자동으로 등록하지 않는다.
    • 스프링 부트는 application.properties에 있는 설정을 참고해서 DataSource를 등록한다. 
      • 스프링 부트는 기본적으로 HikariCP를 DataSource로 등록해준다.
      • Connection Pool 설정을 application.properties에서 처리할 수 있다.
      • DataSourceURL이 지정되지 않는 경우, 내장 DB(메모리 DB)를 생성하려고 시도한다. 
    // application.properties
    spring.datasource.url=jdbc:h2:tcp://localhost/~/test
    spring.datasource.username=sa
    spring.datasource.password=

     

     

    TransactionManager : 스프링 부트가 자동 등록 

    • 스프링 부트는 적절한 트랜잭션 매니저(PlatformTransactionManager)를 자동으로 스프링 빈에 등록해준다.
    • 자동으로 등록되는 스프링 빈의 이름은 'transactionManager'다.
    • 개발자가 직접 트랜잭션 매니저를 빈으로 등록하면 스프링 부트는 트랜잭션 매니저를 자동으로 등록하지 않는다. 

    TransactionManager는 DB 접근 기술을 어떤 것을 사용하느냐에 따라 다른 TransactionManager 구현체가 필요하다. 그렇다면 스프링부트는 어떤 것을 기준으로 TransactionManager를 생성해서 등록해줄까? 스프링부트는 현재 등록된 라이브러리를 참고해서 적절한 TransactionManager를 등록해준다.

    Jdbc 라이브러리가 존재할 경우 DataSourceTransactionManager를 등록해준다. JPA를 사용하면 JpaTransactionManager를 등록해준다. 둘다 사용하는 경우에는 JpaTransactionManager를 등록해주는데, JpaTransactionManager는 DataSourceTransactionManager의 대부분의 기술을 대응해줄 수 있기 때문에 등록해준다. 

     

     

    실습 코드 작성

    스프링 부트는 DataSource / TransactionManager를 자동으로 등록해준다. 이를 이용하면 기존 테스트 코드에서 사용하던 TestConfig 설정 클래스의 코드 복잡도를 감소시킬 수 있다.

    기존 코드

    @TestConfiguration
    static class TestConfig {
    
        @Bean
        DataSource dataSource() {
            return new DriverManagerDataSource(URL, USERNAME, PASSWORD);
        }
    
        @Bean
        PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    
        @Bean
        MemberRepositoryV3 memberRepositoryV3() {
            return new MemberRepositoryV3(dataSource());
        }
    
        @Bean
        MemberServiceV3_3 memberServiceV3_3() {
            return new MemberServiceV3_3(memberRepositoryV3());
        }
    
    }
    • 현재 TestConfig 내부 클래스에 @Bean으로 DataSource / TransactionManager를 직접 생성해서 등록해 줌. 

     

    변경 코드

    @TestConfiguration
    static class TestConfig {
    
        private final DataSource dataSource;
    
        public TestConfig(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        @Bean
        MemberRepositoryV3 memberRepositoryV3() {
            return new MemberRepositoryV3(dataSource);
        }
    
        @Bean
        MemberServiceV3_3 memberServiceV3_3() {
            return new MemberServiceV3_3(memberRepositoryV3());
        }
    
    }
    ``` application.properties 특성 추가
    spring.datasource.url=jdbc:h2:tcp://localhost/~/1
    spring.datasource.username=sa
    spring.datasource.password=1
    • TestConfig에 설정 부분이 변경된다.
    • 스프링 부트는 DataSource를 application.properties를 바탕으로 스프링 빈으로 등록해준다.
    • 스프링 부트는 TransactionManager를 현재 등록된 라이브러리를 기준으로 생성해 스프링 빈으로 등록해준다. 

     

    정리

    • 스프링부트가 제공하는 DataSource / TransactionManager의 자동 빈 등록 기능을 사용하는 것이 편리하다.
    • DataSource는 application.properties를 이용해 편리하게 설정을 할 수 있다.

     

    문제

    • 아직까지 Service 계층에 DB 기술 종속적인 부분(SQLException)이 남아있는 것을 볼 수 있다.
    • Repository 계층에서 Service 계층으로 DB 관련 Exception이 누수되는 부분을 처리해야한다. 

    댓글

    Designed by JB FACTORY