💐 Spring/Spring 핵심 기술

3. IoC 컨테이너 3부 : @Autowired

2020. 6. 15. 21:43
목차
  1. 동작 원리
반응형

@Autowired

  • required : 기본값은 true (따라서 못 찾으면 애플리케이션 구동 실패)

 

 

 @Autowired라는 어노테이션이 없는데 어떻게 빈으로 등록이 된걸까?

어떤 빈이 되는 클래스의 
생성자가 오직 하나만 있고 그 생성자의 매개변수 타입이 빈으로 등록이 되어있다면 
@Autowired가 없더라도 자동으로 주입을 시켜준다.

 

 

 

Repository라는 interface 를 구현한 interface는 Spring Data JPA에서 .. LifeCycle .. 어쩌고 에서 bean으로 자동으로 등록해준다.... 그래서 따로 @Autowired라는 어노테이션이 없어도 bean으로 등록이 된다.

 

이렇게 되면 @Autowired 라는 어노테이션이 점점 사라진다고 한다. 이런식으로 코드를 짜면.

 

 

사용할 수 있는 위치

  @Autowired / @Inject를 어디에 붙일까?

 

  •    생성자 ( 어떠한 클래스에 반드시 필요한 의존성이다 하면 생성자)

빈이 없으면 인스턴스를 생성을 하지 못한다. -> 

  •    Setter (만약 *어느 의존성에 대한 Setter를 가지고 있다면 Setter)

    *어느 의존성 -> private final PetRepository pets; 

 

  •    필드 (Setter가 없다면 .. 하지만 @Autowired를 위해서 굳이 Setter를 만들어서까지 할 필요는 없다.)

 

 

 

 

 

내가 어떤 빈을 주입받았는지 확인 하고 싶을때

 

 

 

1.  Runner를 하나 만들어 준다. (implements ApplicationRunner)

 

2. 빈을 주입 받으면, 주입 받은 빈의 클래스이름을 출력하게끔 해준다.

 

3. @Primary - 같은 타입의 빈이 여러개 일때

 

같은 타입의 빈이 여러개여도 @Primary로 등록해주면 그 빈이 주입이 된다.

 

아래는 실행했을때의 출력문 이다.

 

 

 

 

같은 타입의 빈이 여러개일때, 명확하게 표시를 안해주면 오류가 난다.

   

    그리하여 이 오류에 대한 해결책은 다음과 같이 3가지가 있다.

  • @Primary ("이 빈을 받을거다" 라고 마킹하는 용도)
  • 해당 타입의 빈 모두 주입 받기
  • @Qualify (빈 이름으로 주입)

 

@Primary

이 빈을 주입 하도록 표시하는 용도.

 

 

 

@Qualifier (빈 이름으로 주입)  *이 방법보단 @Primary가 더 안전하다.

필드에다가 어노테이션을 붙여준다.

     @Autowired @Qualifier("빈의 이름")

 

 

 

해당 타입의 빈 모두 주입 받기

 

모든 타입의 빈을 주입 받으려면 위에 코드를 추가해주면 된다.

그러면 해당 타입의 모든 빈이 출력이 된다.

 

 

 

 

 

 

동작 원리

  • BeanPostProcessor
    • 새로 만든 빈 인스턴스를 수정할 수 있는 라이프 사이클 인터페이스
  • AutowiredAnnotationBeanPostProcessor extends BeanPostProcessor
    • 스프링이 제공하는 @Autowired @Value 애노테이션 그리고 JSR-330의 @Inject애노테이션을 지원하는 애노테이션 처리기

출처 : http://blog.naver.com/PostView.nhn?blogId=edy5016&logNo=221280377077

 

 

결론부터 말하자면, @Autowired 애노테이션은 BeanPostProcessor라는 라이프 사이클 인터페이스의 구현체인 AutowiredAnnotationBeanPostProcessor에 의해 의존성 주입이 이루어진다.

 

BeanPostProcessor는 빈의 initializing(초기화) 라이프 사이클 이전, 이후에 필요한 부가 작업을 할 수 있는 라이프 사이클 콜백이다.

그리고 BeanPostProcessor의 구현체인 AutowiredAnnotationBeanPostProcessor가 빈의 초기화 라이프 사이클 이전, 즉 빈이 생성되기 전에 @Autowired가 붙어있으면 해당하는 빈을 찾아서 주입해주는 작업을 하는 것이다.

빈 라이프 사이클

위의 빈 라이프 사이클을 보면 12. 빈 초기화 이전, 이후를 BeanPostProcessors가 감싸고 있는 것을 볼 수 있다.

 

AutowiredAnnotationBeanPostProcessor는 하나의 빈으로써 spring IoC 컨테이너에 등록되어 있다.

BeanFactory(ApplicationContext)는 BeanPostProcessor 타입의 빈 = AutowiredAnnotationBeanPostProcessor 빈을 꺼내 일반적인 빈들 = @Autowired로 의존성 주입이 필요한 빈들에게 @Autowired를 처리하는 로직을 적용한다.

 

12단계에는 사실상 이미 빈들이 주입이 되었기 때문에 사용 할 수가 있게된다.

@Service
public class EventLService {

	@Autowired
    MyBookRepository   myBookRepository;

    @PostConstruct
    public void setup(){
        System.out.println(myBookRepository.getClass());
    }
}

출력이 되는 위치가 Runner와는 다르다. Spring-boot가 지원하는 ApplicationRunner는 applicaion이 완전히 구동이 됐을때, 그 다음에 처리가 되는 건데, 이 @PostConstruct 라이프 사이클 같은 경우에는 application 구동중(12 단계)에 찍히게 된다.

 

BeanFactory가 자신 안에 등록되어있는 BeanPostProcessors를 찾게 되고, 그 구현체 중 AutowiredAnnotaionBeanPostProcessor를 각 빈들에게 적용을 시키게 된다. (잘 이해가 안되지만..)

 

 

- AutowiredAnnotationBeanPostProcessor 가 빈으로 등록되어있는지 직접 꺼내서 출력해보자.

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        AutowiredAnnotationBeanPostProcessor bean = applicationContext.getBean(AutowiredAnnotationBeanPostProcessor.class);
        System.out.println(bean);

    }
}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@43c87306

 

 

 

 

 

 

 

반응형
저작자표시 (새창열림)
  1. 동작 원리
'💐 Spring/Spring 핵심 기술' 카테고리의 다른 글
  • 2. IoC 컨테이너 2부 : ApplicationContext와 다양한 빈 설정 방법
  • 1. IoC 컨테이너 1부 : 스프링 IoC 컨테이너와 빈
  • 4. IoC 컨테이너 4부 : @Component와 컴포넌트 스캔
  • 빈을 등록하고 의존성 주입하는 방법
iseunghan
iseunghan
꾸준하게 열심히..
iseunghan
iseunghan

공지사항

  • 어제보다 나은 오늘이 되기 위해 🔥
  • 분류 전체보기 (262)
    • 💐 Spring (14)
      • 개념 및 이해 (2)
      • Spring 핵심 기술 (24)
      • Spring REST API (8)
      • Spring MVC, DB 접근 기술 (7)
      • Spring Security (23)
      • Spring in Action (1)
    • 🌻 JAVA (84)
      • 자바 ORM 표준 JPA 프로그래밍 (20)
      • 알고리즘, 자료구조 (13)
      • 디자인 패턴 (7)
      • 정리정리정리 (43)
      • JUnit (1)
    • 🔖 Snippets (3)
      • Javascript (3)
    • ⚙️ Devops (22)
      • ⛏ Git (11)
      • 🐳 Docker (6)
      • 🐧 Linux (3)
      • 🌈 Jenkins (1)
      • 📬 Kafka (1)
    • 💬 ETC.. (4)
      • 💻 macOS (2)
    • 🌧️ ORM (2)
      • JPA (2)
    • 🐍 Python (3)
    • 📚 Databases (15)
      • 오라클로 배우는 데이터베이스 개론과 실습(2판) (3)
      • RealMySQL 8.0 (8)
    • 🔥 Computer Science (5)
      • 📡 네트워크 (5)
    • 🏷️ 협업 (1)
    • 📜 코딩테스트 (38)
      • BAEKJOON\수학 1, 수학 2 (8)
      • BAEKJOON\재귀 (5)
      • BAEKJOON\브루트 포스 (3)
      • BAEKJOON\정렬 (1)
      • BAEKJOON\백트래킹 (5)
      • BAEKJOON\BFS, DFS (6)
      • BAEKJOON\이분탐색 (1)
      • BAEKJOON\다이나믹 프로그래밍 (9)
      • BAEKJOON\그리디 알고리즘 (0)
    • ✨ ISEUNGHAN (1)

인기 글

전체
오늘
어제
반응형
hELLO · Designed By 정상우.
iseunghan
3. IoC 컨테이너 3부 : @Autowired
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.