리플렉션이 필요한 이유

이전 HTTP 서버에서 커맨드 패턴으로 만든 서블릿은 아주 유용했지만 몇가지 단점이 있었다.

문제1 : 하나의 클래스에 하나의 기능만 만들 수 있다.

기능 하나 만들때마다 클래스를 만들고 구현해야하는데 이는 복잡한 기능에서는 효과적이지만, 간단한 기능을 만들때는 클래스가 너무 많이 만들어지기때문에 부담스럽다.

아래 코드는 간단함에도 불구하고 각각 클래스로 만들어줘야했다.

public class Site1Servlet implements HttpServlet {
    @Override
    public void service(HttpRequest request, HttpResponse response) {
        response.writeBody("<h1>Site1</h1>");
    }
}

public class Site2Servlet implements HttpServlet {

    @Override
    public void service(HttpRequest request, HttpResponse response) {
        response.writeBody("<h1>Site2</h1>");
    }
}

이 문제를 해결할 방법

→ 하나의 클래스에서 다양한 기능을 처리할 수 있게 만들면 된다. → 리플렉션을 이용하면 가능하다.

문제2: 새로 만든 클래스에 대한 URL 매핑을 항상 추가해줘야한다.

public static void main(String[] args) throws IOException {
    ServletManager servletManager = new ServletManager();
    servletManager.add("/", new HomeServlet());
    servletManager.add("/search", new SearchServlet());
    servletManager.add("/site1", new Site1Servlet());
    servletManager.add("/site2", new Site2Servlet());
    servletManager.add("/favicon.ico", new DiscardServlet());

    HttpServer server = new HttpServer(PORT, servletManager);
    server.start();
}

→ 이 부분도 리플렉션을 이용하면 해결이 가능하다.

클래스와 메타데이터

클래스가 제공하는 다양한 정보를 동적으로 분석하고 사용하는 기능을 리플렉션이라고 한다. 리플렉션을 통해 프로그램 실행 중에 클래스, 메서드, 필드 등에 대한 정보를 얻거나 새로운 객체를 생성하고 메서드를 호출하며, 필드의 값을 읽고 쓸 수 있다.