-
[Spring] Spring IoC/DI ContainerServer/Spring 2020. 8. 11. 17:18
안녕하세요 :)
이번에는 스프링 프레임워크에서 가장 중요하다고 여겨지는 컨테이너와 IoC, DI에 대해 알아보겠습니다.
Container
컨테이너는 인스턴스의 생명 주기를 관리하며, 생성된 인스턴스에게 추가적인 기능을 제공합니다.
(ex.Servlet을 실행해주는 WAS는 Servlet 컨테이너를 가지고 있다.)
개발자가 클래스를 작성하기는 했지만, 실제로 메모리에 올리고 실행하는 것은 컨테이너입니다.
컨테이너는 동일한 클래스에 해당하는 요청을 받으면, 또 반복하여 메모리에 올리지 않고 기존에 메모리에 올라간 클래스를 실행하여 그 결과를 웹브라우저에게 전달합니다.
IoC (Inversion of Container)
컨테이너가 개발자가 구현한 코드 대신 객체의 제어권을 갖고 있어 IoC, 즉 제어의 역전이라고 합니다.
개발자가 만든 어떤 클래스나 메소드를 다른 프로그램이 대신 실행해주는 것을 IoC라고 합니다.
아래에 나올 DI는 IoC의 일부라고 생각하시면 됩니다.
IoC Container
IoC 컨테이너는 Bean을 만들어주고 연결해주며 제공해줍니다. (이름 또는 ID, 타입, 스코프로 설정)
하지만, 컨테이너를 직접 쓸 일은 많지 않습니다.
IntelliJ IDE에서는 빈으로 등록된 클래스는 클래스 왼쪽에 녹색 콩 모양이 보인다고 한다. (귀여워..)
@Bean public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { return cm -> { cm.createCache("vets", cacheConfiguration()); }; }
그리고 클래스를 Bean으로 직접 등록할 수도 있는데 위의 코드가 직접 빈을 등록한 경우입니다.
객체로 만들어진 JCacheManagerCustomizer는 Bean으로 등록되어 IoC 컨테이너가 의존성 주입을 해줍니다.
❗️주의할 점 : 의존성 주입은 Bean들 끼리만 가능하다는 것! 즉, IoC 컨테이너는 자신 안에만 들어있는 객체에만 의존성 주입을 해줍니다.
Spring Bean
스프링 IoC 컨테이너가 관리하는 객체를 Bean이라고 합니다.
Bean과 일반 객체의 차이점?!
@Test public void getBean() { // 일반 객체 OwnerController ownerController = new OwnerController(); // Bean OwnerController bean = applicationContext.getBean(OwnerController.class); }
위의 코드와 같이 new 연산자를 사용해서 생성자를 만들어준 ownerController의 경우 Application Container에서 관리하는
Bean이 아니고, 일반 객체입니다.반면, 아래의 applicationContext에서 getBean 함수를 통해 가져온 bean은 Application Context가 알고있는 객체, Application Context가 직접 만들어서 그 안에 담고있는 객체이므로 스프링의 Bean입니다.
Bean으로 등록하는 방법은 Component Scanning과 직접 xml이나 자바 설정 파일에 등록하는 방법이 있습니다.
- Component Scanning
Component Scanning은 어노테이션 처리기가 @Component가 붙은 하위 패키지들의 모든 클래스들을 다 체크하면서 빈으로 등록해주는 방법이다.
그래서 직접 등록하지 않아도 스프링이 IoC Container가 만들어질 때 알아서 빈을 만들어준다.
@Component Scan은 어느 지점부터 찾아야하는지 알려주는 어노테이션이고, 실제 찾게될 어노테이션은 @Component를 갖고 있는 @Controller , @Service등을 찾아가서 빈을 만듭니다.
Repository는 조금 특이한 형태로 빈으로 등록됩니다.
Repository는 스프링 데이터 JPA가 제공해주는 기능에 의해서 빈으로 등록됩니다. 이 경우에는 특정한 어노테이션이 없더라도, 특정한 인터페이스를 구현하고있을 경우 해당 인터페이스의 구현체를 내부적으로 만들어서 빈으로 등록해줍니다. - Bean으로 직접 등록하는 방법
java 파일에 @Bean 어노테이션을 사용해서 직접 Bean을 만들어줍니다.
Bean을 꺼내서 쓰는 방법은 ApplicationContext의 생성자에 의해 직접 꺼내올 수도 있지만, @Autowired 라는 어노테이션을 사용해서 IoC Container 안의 Bean을 꺼내서 사용할 수 있습니다.
- ApplicationContext 생성자에 의해 직접 꺼내오는 방법
getBean()이라는 메서드를 사용해서 IoC Container의 Bean을 꺼내올 수 있다. - @Autowired (이 경우를 더 많이 사용합니다.)
@Autowired
private final OwnerRepository owners;
위와 같이 어노테이션을 사용해서 IoC Container의 Bean을 꺼내올 수 있다.
DI (Dependency Injection)
DI는 의존성 주입이라는 뜻을 가지고 있으며, 클래스 사이이 의존 관계를 빈(Bean) 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말합니다.
의존성을 주입해주는 것이 자기 자신이 아니라 외부이기 때문에 Dependency Injection이라고 부릅니다.
Spring에서 제공하는 IoC/DI Container
- BeanFactory : IoC/DI에 대한 기본 기능을 갖고 있습니다.
- Application Factory : BeanFactory의 모든 기능을 포함하며, 일반적으로 BeanFactory보다 많이 사용됩니다.
트랜잭션처리, AOP등에 대한 처리를 할 수 있습니다.
BeanPostProcessor, BeanFactoryPostProcessor 등을 자동으로 등록하고, 국제화 처리, 어플리케이션 이벤트 등을 처리할 수 있습니다. - BeanPostProcessor : 컨테이너의 기본로직을 오버라이딩하여 인스턴스화와 의존성 처리 로직 등을 개발자가 원하는 대로 구현할 수 있도록 합니다.
- BeanFactoryPostProcessor : 설정된 메타 데이터를 커스터마이징 할 수 있습니다.
'Server > Spring' 카테고리의 다른 글
[Spring] Spring이란? (0) 2020.08.11 [Spring] Maven에 대해 이해하기 (4) 2020.08.11 - Component Scanning