티스토리 뷰

인프런에서 '백기선의 스프링 프레임워크 핵심기술' 이라는 강의를 수강하고 있다.

오늘은 ioc 컨테이너와 빈에 대해서 정리하려고 한다.


강의에서는 ioc를 의존 관계 주입 (Dependency Injection) 이라고도 하며, 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아닌, 주입 받아 

사용하는 방법이라고 정의했다. 

    • 의존객체 : bean

    • 의존 객체 주입 : ioc 컨테이너

ioc 컨테이너는 아래와 같은 그림으로 구성이 되있다. 여기서 가장 상위 인터페이스인 BeanFactory와 ApplicationContext 에 대해 알아보려고 한다.



지금 부터 작성하는 내용은 위에 링크에 소개된 도큐먼트를 간략하게 요약한 내용이다. 먼저 BeanFactory부터 알아보자!

    • Bean Container의 가장 상위 인터페이스

    • 각각의 구별되는 이름을 가진 빈 객체의 명세를 가지고 있는 애플리케이션 컴포넌트의 중앙 저장소

    • BenFactory가 반환하는 Bean 객체는 Scope에 따라 프로토 객체 (proto type design pattern) 와 싱글톤 객체 (singleton design pattern) 가 존재
      그리고 spring 2.0 이후에 Request, Session Scope를 가지는 객체가 추가적으로 등장

    • 일반적으로 생성자나 setter 메소드를 통해 객체를 주입하는 방식보다는, BenFactory 에서 검색해서 가져오는 방식이 더 괜찮은 방식

    • 과거에는 xml에 Bean에 대한 명세와 정의를 하였지만, Java 코드를 통해서도 쉽게 Bean에 대한 정의 가능


다음은 BeanFactory의 구현체 ApplicationContext에 대해 알아보자!
    • 애플리케이션 컴포넌트의 중앙 저장소
    • Bean을 Listable 하게 보관하는 인터페이스를 상속
    • 애플리케이션이 동작하는 동안에는 오직 읽기전용 (read only) 이며, 아래와 서비스 제공
      • ResourceLoader
      • ApplicationEventPublisher
      • MessageSource
      • Bean Life Cycle
위에서 Bean을 과거에는 xml 파일을 통해 관리를 했지만, 현재는 자바 코드를 통해 쉽게 정의가 가능하다고 했다. 
그러면 소스를 통해 빈을 정의하고 등록하는 방법에 대해 간단히 설명하겠다.
bookServie 라는 이름을 가진 Bean을 정의했으며, bookServie Bean은 BookRepository를 인스턴스 멤버를 가진 BookService 클래스이다.
Bean을 정의할 때, 이름을 통해서도 정의할 수 있지만, Type Safety하지 못하기 때문에 클래스로 정의하는 것을 권장한다. 
그러나 IDE가 너무 많은 편의성을 제공하기 때문에 이름을 통해 정의하는 것도 Not Bad !!

<?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="inflearn.spring.spring.service.BookService">
        <!-- default singleton -->
        <!-- name : setter, ref : bean id-->
        <property name="bookRepository" ref="bookRepositoryIdInXml"/>
    </bean>

    <bean id="bookRepositoryIdInXml" class="inflearn.spring.spring.repository.BookRepository"/>

</beans>


위에 같은 정의를 하다보면, 오타 하나로 인해 오류가 발생할 수 있다. 쉽지 않다. Bean 정의를 아래와 같이 좀 더 쉽게도 할 수 있다.!

위와 아래는 동일한 Bean을 생성하는 방식인데 ... 나는 개인적으로, 아니 모두가 아래와 같은 방식이 편할 것이다! 아닌 사람 나와!!

@Configuration
public class ApplicationConfig {

    @Bean
    public BookRepository bookRepository() {
        return new BookRepository();
    }

    @Bean
    public BookService bookService() {
        BookService bookService = new BookService();
        bookService.setBookRepository(bookRepository());

        return bookService;
    }

}


이제는 Bean의 Scope 에 대해 알아보자! 


Scope는 대표적으로 프로토타입과 싱글톤 타입이 존재한다고 했다. 싱글톤은 나와 같은 Single 혼자다. (근데, 나 행복하다! Single도 행복하다! 동정하지마라!)

매번 Bean을 생성하는 것이 아닌, 한번 생성하면 계속 여러 곳에서 사용될 수 있다. (한번 SIngle은 영원한 Single 이라는 것인가?!)

사용자의 요청에 따라 Bean을 매번 같은 객체를 생성하면 비효율적이기 때문에 상태를 갖지 않는 객체라고 한다면 싱글톤이 적합하다고 생각한다.

그리고 Bean의 Scope를 정의하지 않는다면 기본으로 싱글톤이다. 마치 우리가 태어날 때, 기본이 혼자인 것처럼!!


프로토 타입은 getBean() 메소드로 Bean을 가져올 때마다 항상 새로운 객체가 생성되는 타입이다. 

getBean() 메소드에서도 항상 동일한 객체를 반환하는 싱글톤과는 다르다!


만약에 프토토 타입의 Bean 객체 내부에 싱글톤이 있다면, 문제는 없다. 비록 프르토 타입의 Bean이 getBean() 메소드를 호출할 때마다 새로운 객체를 반환한다고 할지라도, 내부에 있는 싱글톤 Bean객체는 항상 동일하기 때문에 문제가 되지 않는다. 그러나 반대는 다르다!


싱글톤 타입 Bean 내부에 프로토 타입의 Bean이 있다면, 문제가 된다. 왜냐면 싱글톤은 매번 동일한 객체를 반환해야 하는데, 내부에 있는 프로토타입은 매번 생성되어야 한다. 그렇기 때문에 문제가 발생할 수 있다. 그리고 이 문제는 프록시를 이용하면 해결할 수 있다. (자세한 것은 각자 알아보자)


인프런 강의를 들으면서, Enviroment (Profile + Property) 에 대한 내용도 있었지만, 간단해서 ... 정리는 패스하겠다!


오늘은 크게, 스프링부트에서 너무나도 당연하고, 손쉽게 사용했던 부분에 대해 간단하게 알아봤다!

지금까지는 모르고 썻지만, 이제는 알고 쓰자!!



'인프런 > SpringFramework technology' 카테고리의 다른 글

[인프런] 2. 스프링 AOP  (0) 2020.07.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함