Ian's Archive 🏃🏻

thumbnail
Resource 어노테이션
Spring
2025.01.22.

@Resource 어노테이션과 @Autowired 어노테이션의 차이

두 어노테이션 모두 의존성을 주입하는 어노테이션이다.

해당 어노테이션을 사용하여 IoC 컨테이너에 등록된 빈 객체를 자동으로 주입한다.

어떤 차이가 있는지 보자

@Autowired

  • 필드, 메서드, 생성자에 사용할 수 있다.

  • Bean의 타입을 사용해서 주입할 빈 객체를 찾는다.

  • 하나의 인터페이스는 한 개의 클래스로만 구현할 수 있다. (두 개 이상의 클래스가 구현하면 안 된다.)

마지막 특징 때문에 @Resource 어노테이션을 사용한다. (@Qualifier 또는 @Primary 어노테이션을 사용해도 된다.)

아래의 예제를 살펴보자

copyButtonText
public interface A {}

@Component
public class B implements A {}

@Component
public class C implements A {}

위와 같은 경우 A를 구현하는 클래스 B, C 모두가 @Component 어노테이션을 사용해 스프링 빈 객체로 등록되어 있는 상태이다. 이후 다른 Service 클래스에서 의존성 주입을 받는다고 가정한다.

copyButtonText
@Service
public class HelloService {

    @Autowired
    private A a;
}

이러한 경우 주입받는 구현체가 B 클래스인지, C 클래스인지 알 수 없다.

@Autowired 어노테이션 사용 시 빈 객체를 찾는 순서는 다음과 같다.

  1. 타입이 같은 빈 객체를 찾는다.

  2. 만약 타입이 같은 빈 객체가 두 개 이상이고, @Qualifier 어노테이션이 붙어있지 않은 경우 이름이 같은 빈 객체를 찾는다.

  3. @Qualifier(또는 @Primary) 어노테이션이 붙어있다면 해당 어노테이션으로 지정된 빈 객체를 찾는다.

@Resource

  • 필드, 메서드에 사용할 수 있다. 생성자에는 사용할 수 없다.

  • Bean의 이름을 사용해서 주입할 빈 객체를 찾는다.

사용 시 아래와 같은 형태로 사용한다.

copyButtonText
@Resource(name = "memberRepository")
private MemberRepository memberRepository;

이처럼 name 값을 지정하여 사용하기 때문에 한 개의 인터페이스를 여러 개의 클래스가 구현해도 상관없다.

@Resource 어노테이션 사용 시 빈 객체를 찾는 순서는 다음과 같다.

  1. name 속성 값으로 지정한 빈 객체를 찾는다.

  2. name 속성이 존재하지 않는다면 동일한 타입을 갖는 빈 객체를 찾는다.

  3. name 속성이 존재하지 않고, 동일한 타입을 갖는 빈 객체가 두 개 이상인 경우-앞서 A, B, C로 예시를 든 경우- 이름이 같은 빈 객체를 찾는다.

  4. name 속성이 존재하지 않고, 동일한 타입을 갖는 빈 객체가 두 개 이상이고, 이름이 같은 빈 객체마저도 없는 경우에는 @Qualifier 어노테이션(또는 @Primary)을 사용해서 주입할 빈 객체를 찾아야 한다.

추가로 @Primary, @Qualifier를 살펴보자

copyButtonText
public interface A {}

@Component
public class B implements A {}

@Component @Primary
public class C implements A {}

같은 타입의 Bean 객체가 여러 개 존재할 때 @Primary 어노테이션이 붙은 클래스가 있다면 해당 빈 객체를 주입한다.

copyButtonText
@Component
@Qulifier("b")
public class B implements A {}

@Component
@Qulifier("c")
public class C implements A {}

@Service
public class HelloService {

    @Autowired @Qulifier("b")
    private A a;
}

qualifier value가 b로 설정된 클래스는 B 클래스임을 뜻한다. 따라서 위 예시에서는 필드 이름을 a로 하더라도 B 클래스로 구현된 빈 객체가 주입될 것이다.

Thank You for Visiting My Blog, I hope you have an amazing day 😆
© 2023 Ian, Powered By Gatsby.