Spring 입문주차/2주차

5. IoC Container와 Bean

note994 2024. 8. 19. 21:19

이전 강의를 통해 DI를 사용했을 때의 장점을 살펴 보았다.

그런데 DI를 사용하기 위해서는 객체 생성이 우선되어야 한다.

그렇다면 언제 어디서 누가 객체를 생성해야 할까?

바로 Spring 프레임워크가 필요한 객체를 생성하고 관리하는 역할을 대신 해준다.

빈(Bean) : Spring이 관리하는 객체

Spring IoC 컨테이너 : Bean을 모아둔 컨테이너

 

Bean으로 주입받고 있는 생성자나 메서드는 왼쪽에 커피콩 아이콘이 보인다.


JdbcTemplate 객체

MemoRepositroy의 생성자로 JdbcTemplate를 받는데, 이는 기본적으로 Spring에서 자동으로 주입해주는 Bean이다. 왼쪽에 커피콩 아이콘이 보이는것으로 확인할 수 있다.


이전 강의에서 오류발생 부분, bean이 없다고 말한다.

 

외부에서 주입을 받을 때는 bean 객체만 주입이 가능하다. 왜냐하면 이걸 넣어주는것이 Spring이기 때문이다.

 

그래서 bean 객체로 등록이 되어야 한다.


Bean을 등록하는 방법

현재 Memoservice의 bean을 찾을 수 없어 오류가 발생한다.

 

해결을 위해 bean을 등록할 클래스인 Memoservice 클래스로 가본다.

Memoservice 클래스

등록할 클래스 윗부분에 사진처럼 @Component 를 추가해준다. 그러면 Controller에 있었던 오류가 사라진다.

 

대신 Memoservice의 생성자에서 오류가 발생했다. 이는 마찬가지로 MemoRepository 클래스 또한 bean으로 등록되어있지 않기 때문이다.

MemoRepository 클래스

MemoRepository 클래스에도 똑같이 @Component를 추가해주면 오류가 사라진다.


Spring은 어떻게 @Component가 달린 클래스들을 Bean으로 등록할까?

MemoApplication 으로 가보자.

Ctrl 을 누른 상대로 @SpringBootApplication을 클릭해보면

@ComponentScan 애노테이션이 보인다.

 

이 애노테이션이 현재 package 및 하위 package를 전부 확인하면서 @Component가 설정되어있는 클래스를 찾아서 bean으로 등록해준다.

 

MemoApplication은 패키지의 가장 상단에 위치해 있다.  

 

그리고 Bean으로 등록되면 그 객체의 이름이 앞 글자의 대문자를 소문자로 바꿔서 등록이 된다.

 

즉, MemoRepository 클래스를 bean으로 등록하면 memoRepository 라는 이름으로 등록이 된다는 것이다.


@Autowired

그렇다면 클래스에 @ComponentScan만 달아주면 자동으로 Spring에서 주입해주냐?

 

사실은 생성자로 매개변수를 통해 주입받기 위해서는 그 생성자 위에 @Autowired를 달아줘야 한다.

 

하지만 받는 매개변수 주입이 1개일경우는 생략이 가능하기 때문에 넣지 않아도 작동하는 것이다.

 

2개 이상부터는 @Autowired를 달아줘야 한다.

지금은 Bean으로 받는게 1개라서 상관없지만 2개 이상부터는 @Autowired를 달아줘야 한다.


메서드로 주입받는법

set 메서드로 주입받는 방법이다. 

 

객체의 불변성 때문에 보통은 private final로 필드 선언을 하지만 그렇게한다면 생성자를 통한 주입 외의 방법으로는 할 수 없다. 

 

메서드로 주입받고싶다면 사진처럼 final을 빼야한다.


Lombok으로 받는 방법

클래스 위에 @RequiredArgsConstructor를 사용한다.

 

이건 final 필드에 자동으로 Bean을 주입해준다. final이 붙지 않으면 주입하지 않는다.


@AutoWired를 사용하지 않고 IoC 컨테이너에서 수동으로 주입받는 방법

Bean의 이름을 이용하여 수동으로 주입하는 방법

@Component를 사용하여 Bean으로 관리되고 있는 클래스 객체의 이름을 이용하여 수동으로 주입받는 방법이다.

 

그 클래스로 형변환이 필요한것을 알 수 있다.


Bean의 클래스 형식으로 가져오기


3 Layer Annotation

3 Layer Annotation은 Controller, Service, Repository의 역할로 구분된 클래스들을 'Bean'으로 등록할 때 해당 'Bean' 클래스의 역할을 명시하기 위해 사용된다.

1. @Controller, @RestController

2. @Service

3. @Repository

앞으로는 @Component가 아닌 3 Layer Annotiation을 사용해서 'Bean'으로 등록한다.

 

즉, 이때까지 사용했단 @Controller와 @RestController들도 사실 Bean이었다. 이 Bean을 우리가 모르게 내부적으로 주입받아 사용하고 있었던 것이다.