본문 바로가기
Spring/Spring Core

[Section 1] IoC 컨테이너 2부: ApplicationContext와 다양한 빈 설정 방법

by kevinntech 2020. 9. 2.

해당 게시물은 백기선님의 스프링 프레임워크 핵심 기술 강좌를 정리한 내용 입니다.

 

ApplicationContext

빈 설정 파일

 

- 스프링 IoC 컨테이너는 빈 설정 파일이 필요하다. 

 

 

빈을 등록(설정)하는 방법과 의존성 주입

 

1) application.xml에 빈을 등록하는 방법

 

① 빈(Bean) 등록 및 의존성 주입

 

     다음과 같이 빈(Bean)으로 등록할 클래스를 작성한다.

 

[BookService.java]

public class BookService {

    // BookService가 BookRepository를 사용한다고 가정
    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

 

     resources 디렉토리 아래에 application.xml 파일을 다음과 같이 작성 한다.

 

[application.xml]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bookService"
          class="me.whiteship.springapplicationcontext.BookService">
        <property name="bookRepository" ref="bookRepository"></property>
    </bean>

    <bean id="bookRepository"
          class="me.whiteship.springapplicationcontext.BookRepository">
    </bean>

</beans>

 

     위의 코드에서는 bookService를 빈으로 등록하고 bookService는 bookRepository 빈을 주입 받는다.

 

     <bean> 태그는 빈을 등록하는 태그이다.

     <bean> 태그의 id는 빈을 구분할 때 사용하는 이름을 의미하며 camel-case로 작성한다.

                   ""            class는 빈의 타입을 의미한다.


     <property> 태그는 setter를 이용하여 의존성을 주입 받을 때 사용한다.
     <property> 태그의 name은 setter의 이름에서 가져온 것이며  ref는 (해당 setter의 매개변수로 전달 될 수 있는)

     다른 bean 의 id를 참조한다.

 

 

② 빈(Bean)을 사용

 

      빈 설정 파일을 사용하는 ApplicationContext를 ClassPathXmlApplicationContext 클래스를 이용하여 만든 다음,

      Bean을 사용 할 수 있다.

 

Applicationcontext context = new ClassPathXmlApplicationContext("application.xml");

 

      해당 방법은 빈을 일일이 등록 해야 하기 때문에 번거롭다. 이러한 이유로 등장한 것이 <context:component-scan> 이다. 

 

 

2) application.xml 과 <context:component-scan> 태그를 활용한 빈 등록

 

     빈 설정 파일(application.xml)에  <context:component-scan> 태그를 이용하면 base-package에서 부터

 

     @Component와 이를 확장한 애노테이션(@Service, @Repository, @Controller)을 스캔하여 해당 클래스를

 

     빈으로 등록한다.

 

<context:component-scan base-package="me.whiteship.springapplicationcontext"/>

 

     그리고 @Autowired 애노테이션을 사용하여 빈을 주입 받을 수 있다.  즉, 컨테이너에서 빈을 꺼낼 수 있다.

 

[BookService.java]

@Service
public class BookService {

    @Autowired
    BookRepository bookRepository;

    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

 

3) Java 설정 파일

 

     빈 설정 파일을 xml이 아닌 Java로 만들 수 없을까? 라는 생각에 등장한 것이 바로 Java 설정 파일이다.

 

     방금 전까지 선언 했던 애노테이션(@Repository, @Service, @Autowird)을 모두 제거한다. 


     그리고 @Configuration을 붙인 ApplicationConfig 클래스를 작성한다.

 

     ① 빈(Bean) 등록 및 의존성 주입

 

           Java 설정 파일을 이용하여 빈 등록 및 의존성 주입을 한다.

 

            @Configuration
             public class ApplicationConfig {

                  @Bean

                   public [등록할 빈의 타입] [빈의 id]() { 

                        return new [등록할 빈의 타입](); 
                  }

              }
           

           메서드의 리턴 타입 == 등록할 빈의 타입

           메서드명 == 빈의 id

 

           @Configuration : 스프링 IoC 컨테이너에게 해당 클래스가 빈 설정 클래스인 것을 알려준다.


           @Bean 메서드의 실행 결과로 반환되는 객체를 Bean으로 등록한다. (클래스에 @Bean 선언 불가능)

                              @Configuration이 선언된 클래스 내에 있는 메서드에 사용된다.

                              보통 외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용된다. 

 

[ApplicationConfig.java]

@Configuration
public class ApplicationConfig {

    @Bean
    public BookRepositry bookRespository() {
      return new BookRepository();
    }

    @Bean
    public BookService bookService() {
      BookService bookService = new BookService();
      bookService.setBookRepositry(bookRepository());  // setter를 사용한 의존성 주입
       return bookService;
    }
}

 

     ② 빈(Bean)을 사용

 

          빈 설정 파일을 사용하는 ApplicationContext를  AnnotionConfigApplicationContext 클래스를 이용하여 만든 다음,

          Bean을 사용 할 수 있다.

 

ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class)

 

4) Java 설정 파일에 @ComponentScan를 활용한 빈 등록 

 

     앞서 살펴본 Java 설정도 Bean을 일일이 등록해야 하는 번거로움이 있어서  xml에서 처럼 컴포넌트 스캔을 사용 할 수 있다. 

 

     @ComponentScan 애노테이션을 이용하여 지정한 Class가 위치한 곳부터 컴포넌트 스캔을 하여 Bean을 등록한다.

 

     ① 빈(Bean) 등록 및 의존성 주입

 

@Configuration
// 해당 class가 위치한 곳부터 Component Scan을 한다.
@ComponentScan(basePackageClasses = DemoApplication.class) 
public class ApplicationConfig { 

}

 

     basePackages로 class path를 사용 할 수도 있지만 basePackageClasses가 더 type-safe 하다.

 

     ② 빈(Bean)을 사용

 

          빈 설정 파일을 사용하는 ApplicationContext를  AnnotionConfigApplicationContext 클래스를 이용하여 만든 다음,

          Bean을 사용 할 수 있다.

 

5) @SpringBootApplication 

 

     @SpringBootApplication는 내부적으로 @Configuration과 @ComponentScan 애노테이션이 포함되어 있기 때문에

 

     @SpringBootApplication이 붙어 있는 클래스 자체가 Bean 설정 파일이다.

 

     그래서 SpringBoot의 경우, ApplicationConfig 파일이 필요 없다.

 

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 

 

 

댓글