Home > CS > 2024 > πŸ’Ύ [CS] 싱글톀 νŒ¨ν„΄

πŸ’Ύ [CS] 싱글톀 νŒ¨ν„΄
CS

πŸ’Ύ [CS] 싱글톀 νŒ¨ν„΄.

1️⃣ 싱글톀 νŒ¨ν„΄(Singleton pattern)

  • 싱글톀 νŒ¨ν„΄(singleton pattern)은 ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ— 였직 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ κ°€μ§€λŠ” νŒ¨ν„΄μž…λ‹ˆλ‹€.
  • ν•˜λ‚˜μ˜ 클래슀λ₯Ό 기반으둜 μ—¬λŸ¬ 개의 κ°œλ³„μ μΈ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ 수 μžˆμ§€λ§Œ, κ·Έλ ‡κ²Œ ν•˜μ§€ μ•Šκ³  ν•˜λ‚˜μ˜ 클래슀λ₯Ό 기반으둜 단 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ 이λ₯Ό 기반으둜 λ‘œμ§μ„ λ§Œλ“œλŠ”λ° μ“°μž…λ‹ˆλ‹€.
    • 보톡 λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° λͺ¨λ“ˆμ— 많이 μ‚¬μš©ν•©λ‹ˆλ‹€.
  • ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ 놓고 ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€λ₯Ό λ‹€λ₯Έ λͺ¨λ“ˆλ“€μ΄ κ³΅μœ ν•˜λ©° μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ λ“œλŠ” λΉ„μš©μ΄ μ€„μ–΄λ“œλŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.
    • ν•˜μ§€λ§Œ μ˜μ‘΄μ„±μ΄ λ†’μ•„μ§„λ‹€λŠ” 단점이 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ Javaμ—μ„œμ˜ 싱글톀 νŒ¨ν„΄.

  • Javaμ—μ„œ Singleton νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜λŠ” 방법은 μ—¬λŸ¬ κ°€μ§€κ°€ μžˆμ§€λ§Œ, κ°€μž₯ 일반적으둜 μ‚¬μš©λ˜λŠ” 방법 쀑 λͺ‡ κ°€μ§€λ₯Ό μ†Œκ°œν•˜κ² μŠ΅λ‹ˆλ‹€.
    • Eager Initialization(μ¦‰μ‹œ μ΄ˆκΈ°ν™”)
    • Lazy Initialization(μ§€μ—° μ΄ˆκΈ°ν™”)
    • Thread-safe Singleton(μŠ€λ ˆλ“œ μ•ˆμ „ 싱글톀)
      • Synchronized Method
      • Double-checked Locking
    • Bill Pugh Singleton(Holder 방식)

1️⃣ Eager Initialization(μ¦‰μ‹œ μ΄ˆκΈ°ν™”)

  • κ°€μž₯ κ°„λ‹¨ν•œ λ°©λ²•μœΌλ‘œ, ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œ μ¦‰μ‹œ Singleton μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
    public class Singleton {
      // μœ μΌν•œ μΈμŠ€ν„΄μŠ€ 생성
      private static final Singleton instance = new Singleton();
        
      // private μƒμ„±μž: μ™ΈλΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€ 생성을 λ°©μ§€
      private Singleton() {}
        
      // μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œ
      public static Singleton getInstance() {
          return instance;
      }
    }
    
  • 이 방법은 κ°„λ‹¨ν•˜κ³  μ§κ΄€μ μ΄μ§€λ§Œ, ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œ λ°”λ‘œ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κΈ° λ•Œλ¬Έμ—, μΈμŠ€ν„΄μŠ€κ°€ μ‚¬μš©λ˜μ§€ μ•Šλ”λΌλ„ λ©”λͺ¨λ¦¬λ₯Ό μ°¨μ§€ν•˜κ²Œ λ©λ‹ˆλ‹€.

2️⃣ Lazy Initialization(μ§€μ—° μ΄ˆκΈ°ν™”)

  • μΈμŠ€ν„΄μŠ€κ°€ 처음으둜 ν•„μš”ν•  λ•Œ μƒμ„±λ˜λ„λ‘ ν•©λ‹ˆλ‹€.
    • 이 방법은 μ΄ˆκΈ°ν™”μ— λ“œλŠ” λΉ„μš©μ΄ 큰 경우 μœ λ¦¬ν•©λ‹ˆλ‹€.
      ```java
      public class Singleton {
      // μœ μΌν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μ €μž₯ν•  λ³€μˆ˜ (μ΄ˆκΈ°μ—λŠ” null)
      private static Singleton instance;

    // private μƒμ„±μž: μ™ΈλΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€ 생성을 λ°©μ§€
    private Singleton() {}

    // μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œ (ν•„μš”ν•  λ•Œλ§Œ 생성)
    public static Singleton getInstance() {
    if (instance == null) {
    instance = new Singleton();
    }
    return instance;
    }
    }
    ```

  • 이 방법은 닀쀑 μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ μ•ˆμ „ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, 좔가적인 동기화가 ν•„μš”ν•©λ‹ˆλ‹€.

3️⃣ Thread-safe Singleton(μŠ€λ ˆλ“œ μ•ˆμ „ 싱글톀)

  • 닀쀑 μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ μ•ˆμ „ν•˜κ²Œ Lazy Initialization을 κ΅¬ν˜„ν•˜λ €λ©΄ 동기화λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

1️⃣ Synchronized Method

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    // synchronized ν‚€μ›Œλ“œλ‘œ μŠ€λ ˆλ“œ μ•ˆμ „ν•˜κ²Œ λ§Œλ“¦
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 이 방법은 μ•ˆμ „ν•˜μ§€λ§Œ, μ„±λŠ₯에 μ•½κ°„μ˜ 영ν–₯을 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 'synchronized' 둜 인해 μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— β€˜getInstance()β€˜ λ₯Ό ν˜ΈμΆœν•  λ•Œ 병λͺ© ν˜„μƒμ΄ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ Double-checked Locking

  • 이 방법은 μ„±λŠ₯κ³Ό μŠ€λ ˆλ“œ μ•ˆμ „μ„±μ„ λͺ¨λ‘ κ³ λ €ν•œ μ΅œμ ν™”λœ λ°©μ‹μž…λ‹ˆλ‹€.
    public class Singleton {
      private static volatile Singleton instance;
        
      private Singleton() {}
        
      public static Singleton getInstance() {
          if (instance == null) {
              synchronized (Singleton.class) {
                  if (instance == null) {
                      instance = new Singleton();
                  }
              }
          }
          return instance;
      }
    }
    
  • μ—¬κΈ°μ„œ 'volatile' ν‚€μ›Œλ“œλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κ°€ μŠ€λ ˆλ“œ 간에 μ˜¬λ°”λ₯΄κ²Œ μ΄ˆκΈ°ν™”λ˜λ„λ‘ 보μž₯ν•©λ‹ˆλ‹€.

4️⃣ Bill Pugh Singleton(Holder 방식)

  • 이 방법은 Lazy Initialization을 μ‚¬μš©ν•˜λ©΄μ„œλ„, μ„±λŠ₯κ³Ό μŠ€λ ˆλ“œ μ•ˆμ „μ„±μ„ λͺ¨λ‘ 보μž₯ν•©λ‹ˆλ‹€.
    public class Singleton {
        
      private Singleton() {}
        
      // SingletonHolderκ°€ 클래슀 λ‘œλ“œ μ‹œμ μ— μ΄ˆκΈ°ν™”λ¨
      private static class SingletonHolder {
          private static final Singleton INSTANCE = new Singleton();
      }
        
      public static Singleton getInstance() {
          return SingletonHolder.INSTANCE;
      }
    }
    
  • 이 방법은 λ‚΄λΆ€ 정적 ν΄λž˜μŠ€κ°€ JVM에 μ˜ν•΄ 클래슀 λ‘œλ“œ μ‹œ μ΄ˆκΈ°ν™”λ˜λ―€λ‘œ, κ°€μž₯ ꢌμž₯λ˜λŠ” 방식 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.
    • ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œ μ΄ˆκΈ°ν™”κ°€ μ΄λ£¨μ–΄μ§€λ―€λ‘œ, λ™κΈ°ν™”λ‚˜ 좔가적인 μ½”λ“œ 없이도 μŠ€λ ˆλ“œ μ•ˆμ „μ„±μ„ 보μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

3️⃣ Spring Boot와 MySQL λ°μ΄ν„°λ² μ΄μŠ€μ˜ μ—°κ²° 그리고 μ‹±κΈ€ν„΄ νŒ¨ν„΄.

  • Spring Bootμ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, λ‚΄λΆ€μ μœΌλ‘œ β€˜μ‹±κΈ€ν„΄ νŒ¨ν„΄β€™ 이 μ‚¬μš©λ©λ‹ˆλ‹€.
    • κ·ΈλŸ¬λ‚˜ 이 νŒ¨ν„΄μ„ 직접 κ΅¬ν˜„ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€.
      • β€˜Spring Framework’ μžμ²΄κ°€ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ„ ν™œμš©ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 및 관리와 κ΄€λ ¨λœ β€˜Bean(객체)’ 을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.

1️⃣ Spring Boot와 μ‹±κΈ€ν„΄ νŒ¨ν„΄.

  • Spring FrameworkλŠ” 기본적으둜 각 Bean을 μ‹±κΈ€ν„΄ μŠ€μ½”ν”„λ‘œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • μ΄λŠ” νŠΉμ • 클래슀의 μΈμŠ€ν„΄μŠ€κ°€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ»¨ν…μŠ€νŠΈ λ‚΄μ—μ„œ ν•œ 번만 μƒμ„±λ˜μ–΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ—μ„œ κ³΅μœ λ¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

2️⃣ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°μ—μ„œμ˜ μ‹±κΈ€ν„΄ νŒ¨ν„΄ μ‚¬μš©.

    1. DataSource Bean.
      • Spring Bootμ—μ„œ MySQLκ³Ό 같은 λ°μ΄ν„°λ² μ΄μŠ€μ— μ—°κ²°ν•  λ•Œ 'DataSource' λΌλŠ” 'Bean' 을 μƒμ„±ν•˜μ—¬ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
      • 이 'DataSource' κ°μ²΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 연결을 κ΄€λ¦¬ν•˜λŠ” 역할을 ν•˜λ©°, Spring은 이 'Bean' 을 μ‹±κΈ€ν„΄μœΌλ‘œ μƒμ„±ν•˜κ³  κ΄€λ¦¬ν•©λ‹ˆλ‹€.
      • 즉, Spring μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œλŠ” 'DataSource' 객체가 ν•˜λ‚˜λ§Œ μƒμ„±λ˜μ–΄ λͺ¨λ“  λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° μš”μ²­μ—μ„œ μž¬μ‚¬μš©λ©λ‹ˆλ‹€.
    1. EntityManagerFactory 및 SessionFactory.
      • JPAλ‚˜ Hibernate와 같은 ORM을 μ‚¬μš©ν•˜λŠ” 경우, 'EntityManagerFactory' λ‚˜ 'SessionFactory' 와 같은 객체도 μ‹±κΈ€ν„΄ νŒ¨ν„΄μ— μ˜ν•΄ κ΄€λ¦¬λ©λ‹ˆλ‹€.
      • 이듀 κ°μ²΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ²˜λ¦¬ν•˜κ³  νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•˜λ©°, μ—­μ‹œ Spring에 μ˜ν•΄ μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ©λ‹ˆλ‹€.
    1. Spring의 μ‹±κΈ€ν„΄ 관리.
      • Spring은 κ°œλ°œμžκ°€ 'Bean' 을 직접 μ‹±κΈ€ν„΄μœΌλ‘œ 관리할 ν•„μš”κ°€ 없도둝, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ»¨ν…μŠ€νŠΈ λ‚΄μ—μ„œ 'Bean' 을 μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
      • λ°μ΄ν„°λ² μ΄μŠ€μ™€μ˜ μ—°κ²° κ΄€λ ¨ ν΄λž˜μŠ€λ“€μ΄ 이 'Bean' λ“€λ‘œ κ΅¬μ„±λ˜λ©°, μ΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 연결이 효율적이고 μΌκ΄€λ˜κ²Œ κ΄€λ¦¬λ˜λ„λ‘ 보μž₯ν•©λ‹ˆλ‹€.

3️⃣ μ˜ˆμ‹œ: Spring Bootμ—μ„œ MySQL μ—°κ²° μ„€μ •.

  • Spring Bootμ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•˜κΈ° μœ„ν•œ 일반적인 섀정은 'application.properties' νŒŒμΌμ΄λ‚˜ 'application.yml' νŒŒμΌμ— λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 정보λ₯Ό μΆ”κ°€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  • 이 섀정은 Spring Bootκ°€ 'DataSource' 'Bean' 을 μžλ™μœΌλ‘œ μƒμ„±ν•˜λ„λ‘ ν•˜λ©°, 이 'Bean' 은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ©λ‹ˆλ‹€.

4️⃣ ✏️ μš”μ•½

  • Spring Bootμ—μ„œ MySQLκ³Ό 같은 λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, Spring은 λ‚΄λΆ€μ μœΌλ‘œ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • 'DataSource', 'EntityManagerFactory' λ“±μ˜ 객체가 μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λ©°, 이λ₯Ό 톡해 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 μΌκ΄€λ˜κ³  효율적인 λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리가 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.
      • Spring μžμ²΄κ°€ 이 νŒ¨ν„΄μ„ μ²˜λ¦¬ν•˜λ―€λ‘œ, κ°œλ°œμžλŠ” λ³„λ„λ‘œ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

4️⃣ Java Servlet μ»¨ν…Œμ΄λ„ˆμ™€ MySQL λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 그리고 μ‹±κΈ€ν„΄ νŒ¨ν„΄.

  • Java Servlet μ»¨ν…Œμ΄λ„ˆμ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, μ‹±κΈ€ν„΄ νŒ¨ν„΄μ΄ 일반적으둜 μ‚¬μš©λ©λ‹ˆλ‹€.
    • λ‹€λ§Œ, 이 νŒ¨ν„΄μ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œμ—μ„œ 직접 κ΅¬ν˜„λ˜λŠ” 것이 μ•„λ‹ˆλΌ, μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆλ‚˜ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€.

1️⃣ JDBC DataSource

  • μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆ(예: Tomcat, Jetty)μ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ„€μ •ν•  λ•Œ 보톡 'DataSource' λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
    • 이 'DataSource' κ°μ²΄λŠ” 보톡 μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λ©°, λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 풀을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • Connection Pooling
    • μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆλŠ” λ°μ΄ν„°λ² μ΄μŠ€ 연결을 κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μ—°κ²° 풀링(Connection pooling)을 μ‚¬μš©ν•©λ‹ˆλ‹€.
      • μ—°κ²° 풀은 μ—¬λŸ¬ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 미리 μƒμ„±ν•˜κ³  μž¬μ‚¬μš©ν•˜λ„λ‘ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • μ—°κ²° 풀을 κ΄€λ¦¬ν•˜λŠ” κ°μ±„λŠ” 'DataSource' 이고, μ΄λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜μ–΄, μ—¬λŸ¬ μ„œλΈ”λ¦Ώμ—μ„œ λ™μΌν•œ 'DataSource' 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ 효율적으둜 λ°μ΄ν„°λ² μ΄μŠ€μ— μ—°κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ˜ ν™œμš©.

  • DataSource 객체
    • μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆλŠ” 보톡 'DataSource' 객체λ₯Ό μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
      • 'DataSource' λŠ” λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 풀을 κ΄€λ¦¬ν•˜λ©°, 이 객체가 ν•œ 번만 μƒμ„±λ˜μ–΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 μž¬μ‚¬μš©λ©λ‹ˆλ‹€.
  • Connection 객체
    • 각 μš”μ²­λ§ˆλ‹€ λ°μ΄ν„°λ² μ΄μŠ€ 연결이 ν•„μš”ν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ 'Connection' 객체가 μƒμ„±λ˜κ±°λ‚˜ ν’€μ—μ„œ κ°€μ Έμ˜€κ²Œ λ©λ‹ˆλ‹€.
      • ν•˜μ§€λ§Œ 'DataSource' μžμ²΄λŠ” μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜κΈ° λ•Œλ¬Έμ—, λ™μΌν•œ 'DataSource' 객체λ₯Ό 톡해 연결이 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

3️⃣ μ˜ˆμ‹œ: Tomcatμ—μ„œ DataSource μ„€μ •

  • Tomcatκ³Ό 같은 μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆμ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€μ™€μ˜ 연결을 μ„€μ •ν•˜λŠ” 일반적인 방법은 'context.xml' νŒŒμΌμ—μ„œ 'DataSource' λ₯Ό μ •μ˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
<Context>
    <Resource name="jdbc/MyDB"
              auth="Container"
              type="javax.sql.DataSource"
              maxTotal="100"
              maxIdel="30"
              maxWaitMillis="10000"
              username="root"
              password="password"
              driverClassName="com.myslq.cj.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/mydb"/>
</Context>
  • 이 섀정은 'jdbc/MyDB' λΌλŠ” JNDI λ¦¬μ†ŒμŠ€λ₯Ό μ •μ˜ν•˜κ³ , 'DataSource' 객체λ₯Ό μƒμ„±ν•˜μ—¬ μ—°κ²° 풀링을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • 이 'DataSource' λŠ” Tomcat λ‚΄μ—μ„œ μ‹±κΈ€ν†€μœΌλ‘œ κ΄€λ¦¬λ©λ‹ˆλ‹€.

4️⃣ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ˜ 이점.

  • νš¨μœ¨μ„±.
    • μ—¬λŸ¬ μ„œλΈ”λ¦Ώμ΄ λ™μΌν•œ 'DataSource' 객체λ₯Ό κ³΅μœ ν•¨μœΌλ‘œμ¨ λ©”λͺ¨λ¦¬μ™€ μžμ›μ„ μ ˆμ•½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • κ΄€λ¦¬μ˜ μš©μ΄μ„±.
    • λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리λ₯Ό 쀑앙화할 수 있으며, μ½”λ“œμ—μ„œ 직접 관리할 ν•„μš” 없이 μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆκ°€ 이λ₯Ό λ‹΄λ‹Ήν•©λ‹ˆλ‹€.

5️⃣ ✏️ μš”μ•½

  • Java Servlet μ»¨ν…Œμ΄λ„ˆμ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, μ‹±κΈ€ν„΄ νŒ¨ν„΄μ€ 주둜 DataSource 객체에 μ μš©λ©λ‹ˆλ‹€.
    • 이 DataSource κ°μ²΄λŠ” μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆμ— μ˜ν•΄ μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λ©°, λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 풀을 톡해 효율적으둜 λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.
      • 이λ₯Ό 톡해 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 μΌκ΄€λ˜κ³  μ„±λŠ₯이 μ΅œμ ν™”λœ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리가 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

3️⃣ Java μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„μ™€ MySQL λ°μ΄ν„°λ² μ΄μŠ€μ˜ μ—°κ²° 그리고 μ‹±κΈ€ν„΄ νŒ¨ν„΄.

  • Java μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„μ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, μ‹±κΈ€ν„΄ νŒ¨ν„΄μ€ μš°μš”ν•œ 역할을 ν•©λ‹ˆλ‹€.
    • κ·ΈλŸ¬λ‚˜ 이 νŒ¨λ„‘μ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œμ—μ„œ 직접 κ΅¬ν˜„λ˜μ§€ μ•ŠμœΌλ©°, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„λ‚˜ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€.

1️⃣ DataSource와 Connection Pooling

  • Java μ• ν”Œλ¦¬κ²Œμ΄μ…˜ μ„œλ²„(예: JBoss/WildFly, GlassFish, WebSphere)μ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ 일반적으둜 'JDBC DataSource' 와 'Connection Pooling' 을 μ‚¬μš©ν•©λ‹ˆλ‹€.
    • μ΄λ•Œ DataSource κ°μ²΄λŠ” μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λ©°, λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°μ˜ νš¨μœ¨μ„±μ„ 높이기 μœ„ν•΄ μ—°κ²° 풀을 μ‚¬μš©ν•©λ‹ˆλ‹€.
  • DataSource μ‹±κΈ€ν„΄ 관리
    • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ™€μ˜ 연결을 κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ DataSourceλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
      • 이 DataSource κ°μ²΄λŠ” μ„œλ²„μ—μ„œ μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ©λ‹ˆλ‹€.
        • 즉, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 λ™μΌν•œ DataSource 객체가 μ‚¬μš©λ©λ‹ˆλ‹€.
    • DataSourceλŠ” λ‚΄λΆ€μ μœΌλ‘œ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 풀을 κ΄€λ¦¬ν•˜λ©°, μ—¬λŸ¬ ν΄λΌμ΄μ–ΈνŠΈ μš”μ²­μ—μ„œ λ™μΌν•œ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 객체λ₯Ό μž¬μ‚¬μš©ν•©λ‹ˆλ‹€.
  • Connection 객체 관리
    • λ°μ΄ν„°λ² μ΄μŠ€μ™€μ˜ μ‹€μ œ 연결을 κ΄€λ¦¬ν•˜λŠ” Connection κ°μ²΄λŠ” 맀번 μƒˆλ‘œμš΄ μš”μ²­μ΄ μžˆμ„ λ•Œλ§ˆλ‹€ DataSourceμ—μ„œ κ°€μ Έμ˜€μ§€λ§Œ, DataSourceλŠ” μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λ―€λ‘œ 전체 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μΌκ΄€λœ μ—°κ²° 풀이 μ‚¬μš©λ©λ‹ˆλ‹€.

2️⃣ Java EE ν™˜κ²½μ—μ„œμ˜ DataSource 관리

  • Java EE μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„μ—μ„œλŠ” 'JNDI(Java Naming and Directory Interface)' λ₯Ό 톡해 DataSourceλ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • μ΄λŠ” μ„œλ²„μ˜ μ „μ—­ μ„€μ •μ—μ„œ κ΄€λ¦¬λ˜λ©°, μ—¬λŸ¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λ™μΌν•œ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 κ³΅μœ ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
  • JNDIλ₯Ό ν†΅ν•œ DataSource μ„€μ • μ˜ˆμ‹œ
    ```xml
- 이 섀정은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„κ°€ μ‹±κΈ€ν„΄ DataSource 객체λ₯Ό μƒμ„±ν•˜κ³  κ΄€λ¦¬ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.

### 3️⃣ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ˜ μ—­ν• .
- **νš¨μœ¨μ„±**
    - μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬λ˜λŠ” DataSourceλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„ μ „μ²΄μ—μ„œ ν•˜λ‚˜μ˜ 객체둜 μœ μ§€λ˜λ©°, 이λ₯Ό 톡해 λ©”λͺ¨λ¦¬μ™€ μžμ› μ‚¬μš©μ΄ μ΅œμ ν™”λ©λ‹ˆλ‹€.
- **일관성**
    - λ™μΌν•œ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 풀을 μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 전방에 걸쳐 λ°μ΄ν„°λ² μ΄μŠ€ 연결이 μΌκ΄€λ˜κ²Œ κ΄€λ¦¬λ©λ‹ˆλ‹€.
- **관리 μš©μ΄μ„±**
    - λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 관리가 μ€‘μ•™ν™”λ˜μ–΄, 각 μ• ν”Œλ¦¬κ²Œμ΄μ…˜μ—μ„œ λ”°λ‘œ 관리할 ν•„μš” 없이 μ„œλ²„μ—μ„œ 톡합 κ΄€λ¦¬λ©λ‹ˆλ‹€.

### 4️⃣ EJBμ™€μ˜ 톡합.
- JavaEE ν™˜κ²½μ—μ„œ EJB(Enterprise JavaBeans)λŠ” 주둜 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„μ—μ„œ κ΄€λ¦¬λ˜λŠ” λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ κ΅¬ν˜„ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
- EJBμ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ‚¬μš©ν•  λ•Œλ„ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ΄ 적용된 DataSourceλ₯Ό 톡해 연결이 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.
```java
@Stateless
public class MyService {
    
    @Resource(lookup = "java:/jdbc/MyDB")
    private DataSource dataSource;
    
    public void doSomething() {
        try (Connection connection = dataSource.getConnection()) {
            // λ°μ΄ν„°λ² μ΄μŠ€ μž‘μ—… μˆ˜ν–‰
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  • 이 μ½”λ“œμ—μ„œ 'dataSource' λŠ” μ„œλ²„μ— μ˜ν•΄ κ΄€λ¦¬λ˜λŠ” μ‹±κΈ€ν„΄ DataSource 객체λ₯Ό μ°Έμ‘°ν•˜λ©°, 이λ₯Ό 톡해 λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.

5️⃣ ✏️ μš”μ•½,

  • Java μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„μ—μ„œ MySQL λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—°κ²°ν•  λ•Œ, μ‹±κΈ€ν„΄ νŒ¨ν„΄μ€ DataSource와 같은 μ€‘μš”ν•œ 객체 관리에 μ‚¬μš©λ©λ‹ˆλ‹€.
    • 이 νŒ¨ν„΄μ„ 톡해 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 연결을 효율적이고 μΌκ΄€λ˜κ²Œ 관리할 수 있으며, μ—°κ²° 풀링을 톡해 μžμ› μ‚¬μš©μ„ μ΅œμ ν™”ν•©λ‹ˆλ‹€.
      • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„κ°€ DataSourceλ₯Ό μ‹±κΈ€ν„΄μœΌλ‘œ κ΄€λ¦¬ν•¨μœΌλ‘œμ¨, μ„œλ²„ μ „λ°˜μ— μΌκ΄€λœ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ œκ³΅ν•˜κ³  νš¨μœ¨μ„±μ„ κ·ΉλŒ€ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.