Spring 12. IoC컨테이너와 Bean

김창민·2024년 8월 13일

BE

목록 보기
32/50

좋은 코드는 응집성은 높게, 결합성은 낮게를 추구한다. IoC를 이용하면 결합성을 낮출 수 있으므로 DI를 이용하게 되는데, 사실 Controller -> Service -> Repository로 받아들인 나는 아직 이해할 수 가 없었다.

강한 결합인 상태에선 Controller에서 Service객체를 만들어서 이용했는데, 역전되면 누가 Service를 만들고 더 나아가 Repository객체는 누가 만드는가 하는 의문이 생길 수 밖에 없다.

Spring IoC 컨테이너

위에서 의문의 답을 바로 말하자면, Spring 프레임워크가 객체를 미리 생성하고 관리해준다. 그렇다면, 미리 생성의 대상은 어떻게 지정되는가 하는 의문이 추가로 발생하게 된다. 이는 @Bean이라는 어노테이션을 통해서 지정이 가능하다. 이 커피콩을 모아둔게 바로 IoC 컨테이너다.

Bean, @Component

@Component라는 어노테이션이 입력된 클래스는 Bean으로 등록이 된다.

@Component
public class MemoService { ... }

Spring을 Run 하면 서버가 열리고, 이때 IoC 컨테이너에 Bean들이 저장된다.
즉, Spring이 MemoService memoService = new MemoService();이 코드를 실행해서 memoService를 IoC 컨테이너에 저장한다. 이때 Bean의 이름은 클래스 에서 맨 앞 글자를 소문자로 바꾼게 된다. MemoService -> memoService

이렇게 되면 IntelliJ에서 해당 클래스 옆에 원두 모양의 아이콘이 생성된다.

@ComponentScan

Spring 서버 실행시 @Component에 설정한 packages를 포함해서 하위 packages들을 전부 확인해서 @Componet대상 클래스를 전부 Bean으로 등록하는데, @ComponentScan은 프로젝트 생성시 ~Application.class@SpringBootApplication에 내장되어 있다.

Bean 사용법

1.Autowired

필드 위에 @Autowired

@Component
public class Service {
		
    @Autowired
    private Repository Repository;
		
		// ...
}

Spring에서 IoC 컨테이너에 저장된 Repository Bean을 해당 필드에 의존성을 주입해준다.

Bean을 주입할 때 사용할 메서드 위에 @Autowired

@Component
public class Service {

    private final Repository Repository;

    @Autowired
    public Service(Repository Repository) {
        this.Repository = Repository;
    }
		
		// ...
}

일반적으론 위처럼 생성자를 사용해서 DI한다.

즉, @Autowired가 있으면 Repository Bean을 주입해준다는 것

@Auto Wired 적용조건

Spring IoC 컨테이너에 의해 관리되는 클래스에서만 가능하다.

@Auto Wired 생략조건

Spring 4.3부터 @Auto Wired 생략이 가능하다. 다만, 생성자 선언이 1개 일 경우만 가능하다.
오버로딩 된 생성자들이 있으면 다 입력해줘야함

ApplicationContext

public MemoService(ApplicationContext context) {
        // 1.'Bean' 이름으로 가져오기
        MemoRepository memoRepository = (MemoRepository) context.getBean("memoRepository");

        // 2.'Bean' 클래스 형식으로 가져오기
        // MemoRepository memoRepository = context.getBean(MemoRepository.class);

        this.memoRepository = memoRepository;
    }

BeanFactory은 Bean의 생성, 관계 설정등의 제어를 담당하는 IoC 객체인데, 이를 상속해서 기능을 확장한 Container가 ApplicationContext다.

ApplicationContext를 이용하면 IoC컨테이너에서 Bean을 수동으로 가져올 수 있다.

3 Layer Annotation

개발자가 편하게 보라고 @Component를

  1. @Controller, @RestController
  2. @Service
  3. @Repository

로 구분해서 역할을 명시하게 해줬다. 그래서 @Component를 사용해도 되지만, 해당 클래스에는 해당 Layer에 일치하는 Component명을 입력하면 된다.

profile
일일 회고 : https://rlackdals981010.github.io/

0개의 댓글