[annotation] @Autowired와 @Qualifier

2024. 4. 24. 14:07·개발/JAVA
728x90
반응형

1. @Autowired

@Autowired는 스프링 프레임워크에서 사용되는 annotation 중 하나로 객체 간의 의존성을 자동으로 주입해 주는 데에 쓰인다.

생성자, 필드, 세터 메서드에 적용할 수 있고 스프링은 알맞은 의존성을 주입하여 코드를 더 유연하고 확장가능하게 만들어준다.

 

2. 적용 예시

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    // 필드
    @Autowired
    private MyRepository myRepository;

    // 생성자
    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    
    // 세터 메서드 주입
    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    
    public void doSomething() {
        myRepository.doSomething();
    }
}

@Component
public class MyRepository {
    public void doSomething() {
        ...
    }
}

코드에서 MyService 클래스는 MyRepository 클래스에 의존하고 있고 MyService 클래스 내의 myRepository 필드를 @Autowired를 통해 주입받고 있다. 스프링은 MyRepository 빈을 찾아서 MyService에 자동으로 주입해 준다.

 

3. 수동 적용 예시

@Autowired를 사용하지 않고 의존성을 주입하려면

public class MyService {
    private MyRepository myRepository;

    // 생성자를 통한 의존성 주입
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // 필드 주입을 통한 의존성 주입
    public void init(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // 세터 메서드를 통한 의존성 주입
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void doSomething() {
        myRepository.doSomething();
    }
}

public class MyRepository {
    public void doSomething() {
        System.out.println("Doing something in MyRepository");
    }
}

public class Main {
    public static void main(String[] args) {
        // 생성자를 통한 의존성 주입
        MyRepository myRepository = new MyRepository();
        MyService myService1 = new MyService(myRepository);

        // 필드 주입을 통한 의존성 주입
        MyService myService2 = new MyService();
        myService2.init(myRepository);

        // 세터 메서드를 통한 의존성 주입
        MyService myService3 = new MyService();
        myService3.setMyRepository(myRepository);

        // 비즈니스 로직 실행
        myService1.doSomething();
        myService2.doSomething();
        myService3.doSomething();
    }
}

어노테이션을 썼을 때 보다 더 복잡해진다.

만약 스프링을 사용하지 않는다면 의존성 주입을 수동으로 해야한다.

 

4. 오류

NoSuchBeanDefinitionException

  • 스프링이 요청한 이름 또는 타입의 빈을 찾을 수 없을 때 발생
  • 주로 @Autowired, ApplicationContext.getBean() 등으로 빈을 요청했을 때, 해당 이름이나 타입의 빈이 존재하지 않을때 발생
  • 간단히, 요청한 빈이 존재하지 않을 때

NoUniqueBeanDefinitionException

  • 동일한 타입의 빈이 여러 개 존재하고, 스프링이 어떤 빈을 선택해야 하는지 모호할 때 발생
  • 주로 @Autowired로 빈을 주입할 때, 동일한 타입의 빈이 여러개 존재하고 어떤 빈을 선택해야 하는지 명시하지 않았을때 발생
  • 간단히, 요청한 빈이 여러개일 때

 

5.  @Qualifier

아래 코드처럼 여러개의 MyRepository 구현체가 있다고 하면

@Component("firstRepository")
public class FirstRepository implements MyRepository {
    public void doSomething() {
        ...
    }
}

@Component("secondRepository")
public class SecondRepository implements MyRepository {
    public void doSomething() {
        ...
    }
}

이를 주입하는 MyService 클래스에서 @Qualifier를 사용하여 특정 빈을 명시

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private MyRepository myRepository;

    @Autowired
    @Qualifier("firstRepository")
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    
    // or
    // @Autowired
    // public MyService(@Qualifier("firstRepository") MyRepository myRepository) {
    //     this.myRepository = myRepository;
    // }

    public void doSomething() {
        myRepository.doSomething();
    }
}

 

혹은 xml에 명시한 빈을 주입할 수도 있다.

 

<!-- beans.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- FirstRepository 빈 정의 -->
    <bean id="firstRepository" class="com.example.FirstRepository"/>

    <!-- SecondRepository 빈 정의 -->
    <bean id="secondRepository" class="com.example.SecondRepository"/>

</beans>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private MyRepository myRepository;

    @Autowired
    @Qualifier("firstRepository")
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void doSomething() {
        myRepository.doSomething();
    }
}
728x90
반응형
저작자표시 (새창열림)

'개발 > JAVA' 카테고리의 다른 글

JAVA-ORACLE 연동 feat.IntelliJ  (0) 2024.05.14
문자열 비교, ==와 equals() 그리고 compareTo()  (0) 2024.05.07
25. JAVA JDBC (Java Database Connectivity) - 3  (0) 2020.06.08
24. JAVA JDBC (Java Database Connectivity) - 2  (0) 2020.06.08
23. JAVA JDBC (Java Database Connectivity) - 1  (0) 2020.06.08
'개발/JAVA' 카테고리의 다른 글
  • JAVA-ORACLE 연동 feat.IntelliJ
  • 문자열 비교, ==와 equals() 그리고 compareTo()
  • 25. JAVA JDBC (Java Database Connectivity) - 3
  • 24. JAVA JDBC (Java Database Connectivity) - 2
joolog
joolog
  • joolog
    JOO
    joolog
  • 전체
    오늘
    어제
    • 분류 전체보기 (165)
      • 개발 (83)
        • JAVA (29)
        • PYTHON (9)
        • AWS (15)
        • DOCKER (2)
        • PERCONA (2)
        • ORACLE (14)
        • MYSQL (1)
        • 알고리즘 (0)
        • 기타 (11)
      • 툴 (5)
        • MARKDOWN (1)
        • GIT (1)
        • DOCKER (1)
        • PyCharm (2)
        • IntelliJ (0)
      • 일상 (35)
        • 맛집 (6)
        • 카페 (2)
        • 요리 (4)
        • 글씨 연습 (2)
        • 그저 일상 (7)
        • 내돈 내산 (11)
        • 홍보 (1)
      • 국내 여행 (1)
      • 해외 여행 (15)
        • 체코-오스트리아 (10)
        • 일본 (5)
      • 암 일지 (26)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 관리
    • 티스토리 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    동위원소
    갑상선 암
    오블완
    자바
    재발
    요양병원
    오닉스 리프3
    저요오드식
    자바JDBC
    성모샘쉼터
    Oracle
    글씨연습
    히로시마
    오라클
    체코
    티스토리챌린지
    mysql
    jdbc
    오스트리아
    잘츠부르크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
joolog
[annotation] @Autowired와 @Qualifier
상단으로

티스토리툴바