본문 바로가기

Develop/Backend 가이드

[Spring] 컨테이너 Container

반응형

Spring Container
Spring Container

컨테이너 Container

Container 는 Spring 의 핵심입니다. Container 는 개발자를 대신하여, Bean 을 생성 / 관리 / 제거합니다. Container 가 Bean 을 관리해주기 때문에, 개발자는 모듈 간에 의존 및 결합으로 인해 발생하는 문제로부터 자유로워 졌습니다. 아래와 같이 독립적인 코드를 작성해서 Annotaion 만 남겨주면 Container 가 개발자가 원하는 상황에 코드를 실행합니다. 따라서 개발자는 메서드가 언제, 어디서 호출되어야 하는지 그리고 메서드를 호출하기 위해 필요한 매개 변수를 준비해서 전달하지 않습니다. Container 가 개발자 대신 알아서 호출합니다.

    @GetMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }

개발자가 Container 개념 즉, Spring framework 의 설계를 이해해야 하는 이유는 Container 가 겉으로 드러나지 않기 때문에 처음 Spring 을 접하면 작동 원리를 이해할 수 없습니다. 왜냐하면 일반적으로 모듈 간에 상호작용은 메서드로 이루어져야 하는데 코드를 보면 이러한 작업을 수행하는 코드가 없기 때문입니다.

    public static void main(String[] args) {
        SpringApplication.run(ConsumingRestApplication.class, args);
        // 개발자가 run 메서드를 호출하지 않지만, Container 에 의해 run 메서드가 수행됩니다.
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
        return args -> {
            Quote quote = restTemplate.getForObject(
                    "https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
            log.info(quote.toString());
        };
    }
}

이렇게 Container 가 개발자를 대신하여 메서드가 호출될 때와 메서드가 필요한 자원을 전달하는 설계 구조를 Inversion of Control (IOC) 이라 합니다. IOC 는 메서드가 필요로 하는 자원을 코드가 실행되는 타임에 전달하는데, 이를 Dependency Injection (DI) 이라 합니다. 예를 들어 Container가 알아서 greeting 메서드가 필요로 하는 name 매개변수를 전달하는 과정과 run 메서드가 필요로 하는 RestTemplate 매개변수를 전달하는 과정 모두 Dependency Injection (DI) 입니다.

NOTE Dependency Injection 은 Reflection 이라는 기술을 기초로 구현되어 있습니다. Reflection 기술은 런타임에 코드의 메타 데이터를 읽는 기술입니다. 특히 메서드의 Signature 를 읽을 수 있고, Signiture 에 메서드가 필요로 하는 매개변수 정보가 있습니다. Dependency Injection 은 Reflection 으로 얻은 코드 데이터로 메서드가 필요로 하는 자원을 런타임에 제공합니다. 저는 자세한 구현을 .NET CLR 로 배웠기 때문에, JVM 은 어떻게 구현하였을지 궁금하군요.

만약 Container를 직접 조작하여 Bean 의 생성 / 관리 / 제거에 관여하고 싶다면, Container 의 설정 정보가 담기 XML 문서를 변경하면 되고, 런타임에 조작하고 싶다면 ApplicationContext 객체를 사용하면 됩니다.

반응형