2020-3-24 다시 시작하는 스프링 - IoC컨테이너

역사

  • 2003년등장.
  • Jave EE와 비교가 되지만 실제로는 Java EE스펙을 구현모음이다.

IoC 컨테이너

@Service
public class BookService {
	private BookRepository bookRepository = new BookRepository;

	public BookService(BookRepository bookRepository) {
		this.bookRepository = bookRepository
	}
}
  • spring에서는 위의 코드처럼 BookRepository를 직접 사용하기보다. 장치를 통해 주입을 해서 사용한다. 이를 Invertion Of Control이라 한다.
  • IoC컨테이너에 들어와있는 객체들을 빈(Bean)이라 한다. => IoC컨테이너가 관리하는 객체!
  • 초창기에는 XML기반으로 injection을 했지만 최근에는 어노테이션을 활용해서 주입을 한다.
  • BeanFactory Interface가 스프링컨테이너의 핵심이다. 실제적으로는 ApplicationContext를 많이 사용한다. ApplicationContext는 BeanFactory를 상속받음.
  • ApplicationContext는 BeanFactory의 기능을 가지고 추가적으로 다른 기능들을 가지고 있다.(ApplicationEvenetPublisher, EnvironmentCapable 등등) 자세한부분 더 보기
  • 의존성 주입을 받으려면 빈(Bean)이여야한다.

BeanFactory

  • 빈컨테이너에 접근하기 위한 최상위 인터페이스이다. ListableBeanFactory, ConfigurableBeanFactory 인터페이스의 경우 특별한 경우 사용된다.

빈(Bean)

  • @Repository, @Service 등으로 빈으로 등록한다.

  • 어노테이션을 통해 빈으로 등록하고, 빈끼리 의존성을 주입할때는 어노테이션을 활용한다.

  • 빈 등록을 하면 기본적으로 싱글톤으로 생성된다. 어느곳에서 호출하든지 늘 같은객체이기 때문에 메모리면으로도 효율적이다.

  • 장점

    • 스코프
      • 싱글톤 : 하나만.
      • 프로토타입 : 매번 다른 객체.
    • 라이프사이클 인터페이스 : 다양한 라이프사이클 인터페이스들을 사용할 수 있다. ex). postcontruct => 빈이 생성이 될때 사용되는 생성자같은메서드?
@RunWith(SpringRunner.class)
public class BookServiceTest {
    @Mock
    private BookRepository bookRepository;
    @Test
    public void save() {
        Book book = new Book();

        when(bookRepository.save(book)).thenReturn(book);
        BookService bookService = new BookService(bookRepository);
        Book result = bookService.save(book);

        assertThat(book.getCreated()).isNotNull();
        assertThat(book.getBookStatus()).isEqualTo(BookStatus.DRAFT);
        assertThat(result).isNotNull();
    }
}

@Service
public class BookService {
    @Autowired
    private BookRepository bookRepository;

    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public Book save(Book book) {
        book.setCreated(new Date());
        book.setBookStatus(BookStatus.DRAFT);
        return bookRepository.save(book);
    }

    @PostConstruct
    public void postContruct() {
        System.out.println("hello world");
    }
}

@Repository
public class BookRepository {
    public Book save(Book book) {
        return null;
    }
}

  • BookRepository를 구현하지 않고서는 BookService를 테스트할 수 없다. 의존성에 관련된 문제, BookService에 대한 단위 테스트를 만들기가 힘들다.
  • 의존성부분을 Mockto를 이용해서 해결을 했다

ApplicationContext

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • spring-boot-starter-web 패키지만 넣어두면 필요한 대부분의 의존성들이 다 들어온다. (aop, beans, context, core, test, web …) => 보통은 위에 코드처럼 하나하나 xml에 넣어야되는걸 한번에 넣어준다.
  • autowire는 기본적으로 byName, byType, constructor, no, default의 속성이 존재
Written on March 24, 2020