본문 바로가기
Spring/인프런 토비의 Spring Boot

섹션 4-8 [독립 실행형 스프링 애플리케이션] 자바코드 구성 정보 사용

by include_hoany 2024. 6. 1.

자바 코드 구성 정보 사용


Spring Container가 사용하는 구성정보를 우리가 만든 코드를 어떻게 오브젝트로 만들어서 Container내에 컴포넌트를 등록해 두고 Spring Container안에 들어있는 우리가  Bean이라고 불리는 오브젝트가 또 다른 오브젝트를 사용한다면 즉 이제 의존하고 있다면 이 관계를 어떻게 맺어줄 것인가 어느 시점에 그 오브젝트를 주입해 줄 것인가 이런 정보들을 Spring Container에다가 구성 정보로 제공을 해줘야합니다. 이러한 구성정보를 제공하는 방법이 여러가지가 있을 수 있지만 예전에는 외부 설정파일을 이용했었지만 요즘은 좀더 쉽고 간결한 여러가지 방법들이 나와있습니다. 그 중 독특한 방법은 Factory Method를 이용하는겁니다.

 

Factory Method

FactoryMethod라는것은 어떤 오브젝트를 생성하는 로직을 담고 있는 그런 메소드 입니다. FeactoryMethod메소드에서 빈 오브젝트를 다 생성을하는겁니다. 생성하고 의존 관계를 주입도 하고 리턴하는 그 오브젝트를 Spring Container에게 Bean으로 등록해서 이후에 사용하면 되는거라고 알려주는겁니다. 

 

애노테이션 구성정보 등록 코드

TobyspringbootApplication.class

package com.tobyspring.tobyspringboot;  
  
  
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;  
import org.springframework.boot.web.server.WebServer;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;  
import org.springframework.web.servlet.DispatcherServlet;  
  
/*  
    Bean을 Spring Container가 인지하기 위해서는 한가지 작업을 더 해야하는데
    그게 뭐냐면 SpringContainer가 Bean오브젝트를 생성하는 Factory Method를 가진 클래스다
    라는것을 인지하도록 클래스 레벨에도 애노테이션을 붙여줘야 합니다.  
    그 어노테이션은 Configuration입니다.
*/  
@Configuration  
public class TobyspringbootApplication {  
  
    /*  
       Bean을 등록할때 FactoryMethod사용하여 오브젝트를 생성할 수 있도록 구현합니다.
       Spring Container가 의존성 주입을 하기 때문에 FactoryMethod에 매개변수로 의전 오브젝트를
       주입받도록 합니다 또한 SpringContainer가 해당 팩토리 메소드를 인지해야하는데
       인지시키기 위해서는 Bean애노테이션을 작성하면 Spring Container가 해당 팩토리 메소드를 인지할 수 있게 됩니다.
     */
    @Bean  
    public HelloController helloController(HelloService helloService) {  
       return new HelloController(helloService);  
    }  
  
    @Bean  
    public HelloService helloService() {  
       return new SimpleHelloService();  
    }  
  
    public static void main(String[] args) {  
  
       /*  
          Spring Container 구현, DispatcherServlet을 사용하기 위해서는
          GenericApplicationContext이 아닌 GenericWebApplicationContext 형식으로 생성해야합니다.  
          앞서 Bean을 우리가 직접 클래스 타입을 구성정보로 등록했다면 섹션 4-8에서는 구성정보를
          어노테이션으로 등록을 합니다. 다만 애노테이션으로 구성정보를 등록할때는 GenericWebApplicationContext
          은 애노테이션 구성정보를 인지할 수 없습니다. 다라서 변경을 해야하는데 AnnotationConfigWebApplicationContext를
          사용하면 애노테이션 구성정보를 Spring Container가 인지할 수 있습니다.
      	*/
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext() {  
          @Override  
          protected void onRefresh() {  
             super.onRefresh();  
             /*  
              Spring Boot에서 Tomcat Sublet 컨테이너를 내장해서 프로그앰에서 코드로
              쉽게 사용할 수 있도록 제공하는 클래스 TomcatServletWebServerFactory
              */
         	 TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory();  
  
       		/*  
            	웹서버 서블릿 컨테이너를 생성하는 함수 serverFactory.getWebServer()
                리턴타입이 디폴트로 설정한 Tomcat이라는 명칭은 사라지고  WebServer명칭으로 된이유는
                스프링 부트가 톰캣 외에 제티나 언더토우같은 다양한 서블릿 컨테이너를 지원할 수 있고
                지원하되 일관된 방식으로 사용할 수 있도록 동작하게할 수 있도록 추상화 해놨기 때문이다.
            */  
             WebServer webServer = serverFactory.getWebServer(servletContext -> {  
                // DispatcherServlet등록  
                servletContext.addServlet("dispatcherServlet",  
                   new DispatcherServlet(this))  
                   .addMapping("/*");  
             });  
  
               /*  
                  Servlet 컨테이너 동작 함수
              */
              webServer.start();  
  
          }  
       };  
  
       // 애토테이션으로 bean구성정보를 등록한다면 bean구성정보를 담고있다고 명시하는 클래스레벨에 명시한 애노테이션  
       // Configuration이 등록된 클래스를 구성정보로 Spring Container에 등록을 해줘야 합니다.
       applicationContext.register(TobyspringbootApplication.class);  
  
       // ApplicationContext가 refresh메소드를 통해 빈 오브젝트를 생성합니다.  
       applicationContext.refresh();  
  
    }  
  
}

단 여기서 중요한 시사점은 @Configuration이 붙은 클래스가 AnnotationConfig을 이용하는 애플ㄹ케이션 컨텍스트에 처음 등록된다는 사실입니다. 왜냐하면 Configuration이 붙은 클래스틑 BeanFactoryMethod를 가지는것 이상으로 전체 애플리케이션을 구성하는데 필요한 중요한 정보들을 많이 넣을 수 있기 때문에 그렇습니다.