새소식

반응형
Study/EffectiveJava

[아이템1] 서비스 제공자 프레임워크

  • -
반응형

대표적인 서비스 제공자 프레임워크 - JDBC

서비스 제공자 프레임워크에서의 제공자는 서비스의 구현체

이 구현체들을 클라이언트에 제공하는 역할을 프레임워크가 통제, 클라이언트를 구현체로부터 분리 

 

서비스 제공자 프레임워크 핵심 컴포넌트

서비스 인터페이스 - 구현체의 동작을 정의 - Connection 

제공자 등록 API - 제공자가 구현체를 등록 할 때 사용 - DriverManager.registerDriver

서비스 접근 API - 클라이언트가 서비스의 인스턴스를 얻을 때 사용 - DriverManager.getConnection

 

서비스 제공자 인터페이스 - 서비스 인터페이스의 인스턴스를 생성하는 팩토리 객체를 설명 - Driver

 

JDBC 예제

Class.forName("oracle.jdbc.driver.OracleDriver"); 
Connection connection = null; 
connection = DriverManager.getConnection
				("jdbc:oracle:thin:@localhost:1121:test", "root", "root");
Class.forName()의 동작 원리
해당 메소드는 물리적인 클래스 파일 명을 인자로 넣어주면, JVM에게 이 클래스를 로드하라고 요청한다.
클래스 로더는 클래스의 메타 데이터를 메서드 영역에 저장 및 Class 객체를 힙 영역에 할당하게 된다.
클래스 로딩이 끝나게 되면 static 필드 및 static 블록이 초기화되며, 이때 제공자 등록 API가 활용된다.

이를 대체하는 것이 java.util.ServiceLoader
      ServiceLoader<HelloService> loader = ServiceLoader.load(HelloService.class);

      Optional<HelloService> helloServiceOptional = loader.findFirst();

      helloServiceOptional.ifPresent(h -> {
         System.out.println(h.hello());
      });

 

DriveManager

public class DriverManager {

    private DriverManager() {
    }

    private static final Map<String, Driver> drivers = new ConcurrentHashMap<String, Driver>();
    public static final String DEFAULT_DRIVER_NAME = "default";

    public static void registerDefaultPrivider(Driver d) {
        System.out.println("Driver 등록");
        registerDriver(DEFAULT_DRIVER_NAME, d);
    }

    public static void registerDriver(String name, Driver d) {
        drivers.put(name, d);
    }

    public static Connection getConnection() {
        return getConnection(DEFAULT_DRIVER_NAME);
    }

    public static Connection getConnection(String name) {
        Driver d = drivers.get(name);
        if (d == null) throw new IllegalArgumentException();
        return d.getConnection();
    }
}

Driver

public class OracleDriver implements Driver {

    static {
        defaultDriver = null;
        Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
        try {
            if (defaultDriver == null) {
                defaultDriver = new OracleDriver();
                DriverManager.registerDriver(defaultDriver); // OracleDriver 등록
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...
    public Connection getConnection() {
        ...
    }
}

 

Connection

public interface Connection  {
	Statement createStatement() throws SQLException;
	PreparedStatement prepareStatement(String sql);
	void commit() throws SQLException;
  	void rollback() throws SQLException;
    ...
}
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.