ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring JPA가 Auto Configuration(자동 설정) 되는 과정 + Connenction, CP
    CS/Spring 2025. 2. 27. 16:49

    JPA 연결 과정

    Data를 연결하고 관리하기 위해서는 원래  다음과 같은 과정들을 거쳐야 합니다.

     

    1. yml 설정

    datasource를 연결하기 위한 설정 정보를 yml로 작성합니다.

     

    2. DataSource 생성

    JPA가 DB와 연결되기 위해서는 DataSource가 필요합니다.

    따라서 DataSource를 생성하고 빈으로 등록합니다.

     

    3. EntityManagerFactory 생성

    JPA는 EntityManagerFactory를 통해 EntityManager를 생성하며, 이 과정에서 DataSource를 사용합니다.

    Spring Boot에서 LocalContainerEntityManagerFactoryBean을 이용해 EntityManagerFactory를 생성합니다.

     

    4. TransactionManager 설정

    JPA는 기본적으로 트랜잭션을 관리하는 TransactionManager가 필요합니다.

    Spring Boot는 JpaTransactionManager를 자동으로 설정합니다.

     

     

    그런데, 우리는 yml설정만 해주면 위와 같은 복잡한 코드를 짜지 않아도 DB와 연결되고 관리됩니다.

    이는 Spring Boot의 자동설정 기능때문입니다.

     

    자동 설정시 내부 동작 과정은 다음과 같습니다.

     

    JPA 자동 설정 내부 동작 과정

    1. Spring Boot가 실행되면, classPath를 스캔하면서 어떤 라이브러리가 있는지 확인합니다.

    2. @SpringBootApplication에 @EnableAutoConfiguration이 포함되어있어, Auto Configuration이 활성화됩니다.

    • spring.factories 파일을 읽어 자동 설정할 클래스들을 로드합니다.

    3. Auto Configuration을 실행합니다. 이때, DataSourceAutoConfiguration와 JpaAutoConfiguration도 포함되어있습니다.

    • 내부적으로 @ConditionalOnClass({EntityManager.class, HibernateJpaVendorAdapter.class})를 사용하여 DataSource 관련된 클래스가 있다면 DataSourceAutoConfiguration이 실행됩니다.
    • JpaAutoConfiguration은 JPA 라이브러리가 존재할 때만 자동 설정이 동작되도록 설정돼있습니다.

    4. yml의 spring.datasource 설정을 읽어서 DataSource 객체를 생성하고 빈으로 등록합니다.

    • 이때, @ConditionalOnMissingBean 어노테이션을 이용해, 해당 빈 객체가 이미 있다면 빈 생성 코드가 실행되지 않고, 없다면 실행됩니다.
    • 빈생성 코드가 실행되면, @ConfigurationProperties(prefix="spring.datasource") 어노테이션이 작동하고 yml에서 해당 설정값을 찾아 DataSourceProperties 객체를 생성하고 빈으로 등록합니다.
    • 마지막으로 @ConditionalOnMissingBean을 통해 같은 이름으로 생성된 빈이 없다면, DataSourceProperties를 이용해 DataSource 객체를 생성하고 빈으로 등록합니다.
    @Configuration
    @ConfigurationProperties(prefix = "spring.datasource")
    public class DataSourceProperties {
        private String url;
        private String username;
        private String password;
        private String driverClassName;
    
        // Getter, Setter
    }
    @Configuration
    @ConditionalOnClass(DataSource.class)  //DataSource 관련 클래스가 있는 경우, JDBC 드라이버가 있는 경우 실행
    @EnableConfigurationProperties(DataSourceProperties.class) //DataSourceProperties 사용
    public class DataSourceAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean //같은 이름으로 등록된 빈이 없다면 실행
        public DataSource dataSource(DataSourceProperties properties) {
            return properties.initializeDataSourceBuilder().build(); 
        }
    }

     

    5. classPath에 Hibernate가 있는지 확인 후에 있으면 yml의 spring.jpa 설정을 적용합니다.

    6. DataSource를 이용해 EntityManagerFactory가 생성되고, @Entity가 선언된 클래스들을 스캔합니다.

    @Bean
    @ConditionalOnMissingBean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        EntityManagerFactoryBuilder builder, DataSource dataSource) {
        
        return builder
            .dataSource(dataSource)
            .packages(getPackagesToScan())  // @Entity가 있는 패키지 자동 스캔
            .persistenceUnit("default")
            .build();
    }

     

    7. EntityManagerFactory를 이용해 TransactionManager를 생성합니다.

    @Bean
    @ConditionalOnMissingBean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

     

     

    DataSource 란?

    DataSource는 JDBC(Java Database Connectivity) API에서 제공하는 인터페이스로, 데이터베이스와의 연결(Connection)을 관리하고 제공하는 역할을 하는 객체입니다. DB연결 정보(jdbc url, username, password, driver class name, connection 개수 등)을 저장합니다.

     

    DB Connection

    애플리케이션과 데이터베이스를 연결하기 위해서는 중간 다리 역할이 있어야합니다. 이 다리역할을 해주는 것을 DB Connection이라고 합니다.

    Java 애플리케이션과 데이터베이스의 Connection 중에 JDBC API가 있습니다.

    JDBC는 Java DataBase Connecion으로, 말그대로 Java와 DataBase의 Connection입니다.

    JDBC를 이용해 Connection을 생성하기 위해서는 db와 연결하고, 끊고하는 작업을 반복해야합니다.

    하지만 DB와 연결하고 Connection 객체를 생성하는 과정은 꽤나 오래걸리고 복잡합니다.

    이런 복잡한 작업을 여러 번 반복해야한다면, 비효율적입니다.

    💡 Connection 객체 생성과정
    ① 애플리케이션에서 DB 드라이버를 통해 커넥션을 조회한다.
    ② DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다. (3 way handshake와 같은 네트워크 연결 동작 발생)
    ③ DB 드라이버는 TCP/IP 커넥션이 연결되면 아이디와 패스워드, 기타 부가 정보를 DB에 전달한다.
    ④ DB는 아이디, 패스워드를 통해 내부 인증을 거친 후 내부에 DB를 생성한다.
    ⑤ DB는 커넥션 생성이 완료되었다는 응답을 보낸다.
    ⑥ DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다.

     

     

    Connection Pool

    싱클턴패턴은 객체를 오직 1개만 생성하고 재활용하는 것을 지향하는 패턴인데요,

    Connection 생성의 비효율성때문에 Connection도 Connection Instance를 미리 생성한 후에 재활용하자는 요구사항이 생기고, 이때 생긴 것이 Connection Pool입니다.

     

    Connection Pool은, JDBC 실행 과정 중에서 생성되어야 할 Connection 객체를 미리 만들어서 pool 이란 곳에서 저장을 해두는 기법입니다.

     

    Connection Pool의 동작 과정은 다음과 같습니다.

    1. 애플리케이션을 시작하는 시점에 커넥션 풀은 필요한 만큼 커넥션을 미리 생성하여 보관합니다. ( 일반적으로 기본값으로 10개를 생성)

    2. 커넥션 풀에 들어있는 Connection 객체는 TCP/IP로 DB와 연결되어 있는 상태이기 때문에 즉시 SQL을 DB에 전달할 수 있습니다.

    3. 즉, DB 드라이버를 통해 새로운 커넥션을 획득하는 것이 아닌 이미 생성되어 있는 커넥션을 참조하여 사용하게 되는 것입니다.

    4. 커넥션 풀에 있는 커넥션을 요청하면 커넥션 풀은 자신이 가지고 있는 커넥션 객체 중 사용가능한 객체 하나를 반환합니다.

     

    HikariCP

    HikariCP란, DataSource 인터페이스의 구현체 중 하나로, Connection Pool을 관리하는 커넥션 풀 라이브러리입니다.

    Spring Boot에서는 기본적으로 HikariCP를 사용하며, 기존의 Apache Commons DBCPTomcat JDBC Pool보다 빠르고 가벼운 성능을 제공합니다.

    'CS > Spring' 카테고리의 다른 글

    Maven 빌드 과정  (0) 2025.03.31
    JPA 개념과 특징  (3) 2025.01.20
    동시성 제어  (1) 2024.09.30
    spring Batch 5.x (2) - 실습  (1) 2024.09.23
    spring Batch  (0) 2024.09.16
Designed by Tistory.