Post

Spring - 2 스프링 IOC

해당 자료는 인프런 백기선님의 예제로 배우는 스프링 입문(개정판) 강의노트입니다..


1. 스프링 IOC

Inversion of Control의 약자로 일반적으로 밑과 같이 OwnerController가 직접 의존성을 관리하는게 아니고

1
2
3
4
class OwnerController {
   private OwnerRepository repository = new OwnerRepository();
}

1
2
3
4
5
6
7
8
9
class OwnerController {
   private OwnerRepository repo;

   public OwnerController(OwnerRepository repo) {
       this.repo = repo;
   } 

   // repo를 사용합니다.
}

이 처럼 OwnerController 밖에서 관리해주는 것을 제어권이 역전되었다고 볼 수 있다.
이를 의존성 주입(DI)이라고 하는데 이것또한 IOC라고 볼 수 있다.
Bean이라는 스프링이 관리하는 객체들의 모임에 저장되어 관리되어진다.

김영한 선생님의 강의를 먼저 듣고나니 이해는 한결 쉬워졌다.


2. 스프링 IOC 컨테이너

  • ApplicationContext와 BeanFactory가 있는데, ApplicationContext가 Bean을 상속받고 다양한 기능을한다.
  • 스프링 IOC 컨테이너 안에 있는 객체끼리 의존성 주입이 가능하다. 복잡한 방법으로 컨테이너 밖의 객체와 연결할 수 있으나 권장하지 않는다.
  • ApplicationContext를 사용할 일은 거의 없다. 왜냐하면 작성할 코드들은 이미 주입이 된 상태이기 때문에 따로 주입할 필요가 없다.
    • 직접 주입을 한 것과 이미 주입된 것을 꺼내어 확인하면 같은 해시값이 찍힌다. 이를 싱글톤으로 빈을 생성한다고 한다.

3. 스프링 빈(Bean)

  • IOC 컨테이너가 관리하는 객체를 빈이라고 부른다.
  • 일반적으로 new로 해서 만든 인스턴스는 Bean이 아니다.
    • 빈으로 만들기 위해서는 2가지 방법이 있다. 컴포넌트 스캔(Component Scanning)과 직접 빈에 등록하는 방법이 있다.
  • 컴포넌트라는 애노테이션(@Component, @Service, @Controller, @Configuration…)이 붙어있는 모든 클래스를 찾아서 빈으로 등록하는 애노테이션 처리기가 등록되어 있다.
    • 예제에서는 @ComponentScan이 범위를 정해준다.
    • Repository는 JPA를 통해 특별하게 관리된다.
  • 직접 빈에 등록하는 방법은 자바설정 파일이나, XML을 쓰느냐에 따라 다르다. 보통 자바설정 파일을 쓰는데 강의에서 쓴 예제는 ‘김영한 선생님’ 강의 포스트의 예제와 비슷하므로 참고하자.(@Configuration 사용)

4. 의존성 주입(Dependency Injection)

  • 생성자에 @Autowired를 붙여 사용할 수 있지만, 어떤 클래스의 생성자가 1개뿐이고 레퍼런스들이 빈에 등록되어 있다면 그 빈을 자동으로 주입해주도록 @Autowired 애노테이션을 스프링 4.3버전 이상부터 생략할 수 있다.
  • Setter()에 @Autowired를 붙이는 방법도 있다. 빈에서 해당 객체를 찾아서 넣어준다. 빈에 등록되어 있지 않은 객체를 넣으려하면 ‘No qualifying bean ~’에러가 발생한다.
  • 스프링에서 권장하는 방법은 생성자를 통해 의존성을 주입하는 방법이다.
    • 필수적으로 사용해야하는 레퍼런스 없이는 인스턴스를 만들지 못하도록 강제할 수 있기 때문이다.
      필드 주입이나 Setter()는 만들 수 있다. 둘은 또한 순환참조가 발생할 수 있다.

1.예제에서의 필드 주입

1
2
@Autowired
	private PetRepository petRepository;

2.생성자 주입

1
2
3
4
5
6
7
	private PetRepository petRepository;

	public OwnerController(OwnerRepository clinicService, VisitRepository visits,PetRepository petRepository) {
		this.owners = clinicService;//원래코드
		this.visits = visits;//원래코드
		this.petRepository = petRepository;
	}

3.Setter주입

1
2
3
4
5
	private PetRepository petRepository;

	public void setPetRepository(PetRepository petRepository) {
		this.petRepository = petRepository;
	}

듣는데 이해는 완벽하지 않아도 이제는 각각 어떤 느낌인지 알 것 같다. 하지만 김영한 선생님의 강의를 듣지 않았다면 이렇게 이해하기 어려웠을 것이다.
백기선 선생님의 강의는 귀에 잘 들어오고 스프링에 대해 다시 한번 듣게되서 어떤 것들을 중점적으로 이해해야할 지 생각이 들게 만든다.

This post is licensed under CC BY 4.0 by the author.