본문 바로가기
(2024-10) 스파르타 내일배움캠프 - 백엔드/Java Reflect

Constructor 예제, 싱글턴에서(2)

by 어뫄어뫄 2024. 11. 26.

1. Reflection 사용

Main.java

  • `Main` 클래스의 `initConfiguration` 메서드는 Java Reflection API를 사용하여 `ServerConfiguration` 클래스의 private 생성자를 호출함
Constructor<ServerConfiguration> constructor =
        ServerConfiguration.class.getDeclaredConstructor(int.class, String.class);
  • 목적: Reflection은 private 생성자와 같은 일반적으로 접근할 수 없는 요소에 접근할 수 있도록 합니다.
  • 주요 단계:
    1. 생성자 가져오기: getDeclaredConstructor를 통해 int와 String 매개변수를 받는 private 생성자를 가져옵니다.
    2. 접근 허용: constructor.setAccessible(true)로 private 접근 제한을 해제합니다.
    3. 인스턴스 생성: constructor.newInstance(8080, "Good Day!")를 호출해 객체를 생성합니다.

ServerConfiguration은 싱글톤 패턴으로 동작하므로, 이 생성자 호출로 초기화된 단일 인스턴스만 사용됩니다.

 

2. 싱글톤 패턴을 사용하는 ServerConfiguration

ServerConfiguration.java

  • 이 클래스는 하나의 인스턴스만 존재하도록 제한합니다:
private static ServerConfiguration serverConfigurationInstance;
  • Private 생성자: 외부에서 직접 인스턴스를 생성할 수 없도록 설정합니다.
  • 싱글톤 구현: serverConfigurationInstance가 null인지 확인한 뒤, 인스턴스를 초기화합니다.
  • 인스턴스 접근: getInstance() 메서드를 통해 초기화된 인스턴스를 반환합니다.

주요 속성:

  • serverAddress: 서버의 네트워크 주소와 포트를 저장합니다.
  • greetingMessage: HTTP 응답 메시지를 설정합니다.

 

3. HTTP 서버 구성

WebServer.java

  • WebServer 클래스는 간단한 HTTP 서버를 구성하고 실행합니다:
  1. 서버 초기화:
    • 싱글톤으로 설정된 ServerConfiguration의 주소와 포트를 사용해 HTTP 서버를 생성합니다.
      HttpServer httpServer = HttpServer.create(ServerConfiguration.getInstance().getServerAddress(), 0);
  2. 요청 핸들러 추가:
    • /greeting 경로를 추가하고, 요청 시 greetingMessage를 응답으로 전송합니다.
      httpServer.createContext("greeting").setHandler(exchange -> {
          String responseMessage = ServerConfiguration.getInstance().getGreetingMessage();
          exchange.sendResponseHeaders(200, responseMessage.length());
          OutputStream responseBody = exchange.getResponseBody();
          responseBody.write(responseMessage.getBytes());
          responseBody.flush();
          responseBody.close();
      });
  3. 서버 시작:
    • 서버를 실행하며, 실행 중인 주소 정보를 콘솔에 출력합니다.
httpServer.start();

 

 

 

setAccessible(boolean flag)

  • 목적: 해당 멤버(필드, 메서드, 생성자 등)의 접근을 제어합니다.
  • 설명:
    • setAccessible(true)를 사용하면, 해당 멤버에 대해 private, protected, default 접근 제한을 무시하고 접근할 수 있게 됩니다.
    • 예제에서는 ServerConfiguration 클래스의 private 생성자를 호출하기 위해 setAccessible(true)를 사용하여 접근을 허용합니다.
     
constructor.setAccessible(true);