@resource VS @autowired

2024. 10. 16. 16:02Web Development/SI 프로젝트

나는 이전 프로젝트에서 autowired 애노테이션을 사용해서 의존성을 주입하였는데, @resource라는 애노테이션을 pms 프로젝트에서 소스분석하다가 발견해서 차이점을 알아보기로 했다.

 

 

<의존 객체 자동 주입(Automatic Dependency Injection)>

 

1. @resource

  • JDK 표준 애노테이션으로, Java EE의 @Resource는 Spring에서도 지원한다.
  • 빈 이름을 기준으로 의존성을 주입한다. 이름이 일치하는 빈을 찾고 주입하는 방식이다.
  • 타입으로 의존성을 주입하는 @Autowired와는 다르게, 기본적으로 이름으로 주입하며, name 속성을 사용하여 구체적으로 어떤 빈을 주입할지를 지정할 수 있다.
  • 만약 name 속성을 명시하지 않으면, 필드 이름과 동일한 빈을 찾아서 주입하게 됩니다. @Resource도 생성자, 필드, 메서드에서 사용할 수 있다.

장점)

  • 정확한 제어: @Resource는 빈의 이름을 기준으로 주입하므로, 주입하려는 빈의 이름이 명확할 때 더 정확하게 컨트롤 할 수 있다.
  • 이름을 통한 명시적 주입: 여러 빈 중 하나를 명시적으로 지정해 주입해야 할 때, 빈의 이름을 명시함으로써 더 구체적인 제어가 가능하다.

단점)

  • 이름 변경에 민감: 이름이 기준이므로 빈의 이름이 바뀌면 코드가 깨질 수도 있다. 즉, 이름이 바뀌면 주입이 실패 가능성이 있다.
  • 타입 검증 어려움: 이름에 의존하기 때문에 타입 불일치가 발생할 수 있다. 즉, 이름은 맞지만 타입이 맞지 않는 객체가 주입될 위험이 존재한다.

사용 예시)

  • 상황: 여러 개의 동일한 타입 빈이 있고, 그중 특정한 이름의 빈을 주입해야 할 때 유용하다.
// 두 개의 빈이 있을 경우
@Component("serviceA")
public class ServiceA implements SomeService {
    // 구현체 A
}

@Component("serviceB")
public class ServiceB implements SomeService {
    // 구현체 B
}

@Resource(name="serviceA")  // 특정 이름의 빈을 주입
private SomeService someService;

이 경우 @Resource는 이름을 명시적으로 지정하므로, 정확히 어떤 빈을 주입할지 명확하게 컨트롤할 수 있습니다.

 

 

2. @autowired

  • Spring 전용 애노테이션으로, Spring 컨테이너에서 관리하는 빈을 자동으로 주입하는 역할을 한다.
  • 기본적으로 타입을 기준으로 의존성을 주입한다. 즉, 해당 타입의 빈을 찾아서 주입함.
  • 만약 같은 타입의 빈이 여러 개 존재할 경우, 빈 이름이나 @Qualifier 애노테이션을 함께 사용하여 특정 빈을 선택할 수 있다.
  • required 속성이 있어서, 기본적으로는 주입할 대상이 없으면 오류를 발생시키지만, required = false로 설정하면 대상이 없어도 오류가 발생하지 않는다.
  • @Autowired는 생성자, 필드, 메서드에서 사용할 수 있으며, 가장 일반적으로 사용되는 의존성 주입 방식이다.

장점)

  • 유연성: @Autowired는 기본적으로 타입에 따라 주입하기 때문에, 이름과 상관없이 동일한 타입의 빈이 있을 경우 자동으로 주입된다. 따라서 더 유연한 의존성 주입을 지원함.
  • 편리성: 빈의 이름을 명시하지 않아도 타입에 맞는 빈을 자동으로 찾아 주입하므로 코드가 간결해진다.
  • 타입 안전성: 주입하려는 객체의 타입이 명확하게 보장되기 때문에, 의존성 주입 시 타입 불일치 오류가 줄어든다.

단점)

  • 여러 빈이 존재할 때의 모호성: 같은 타입의 빈이 여러 개 있을 경우, 어떤 빈을 주입할지 모호해질 수 있다. 이때는 @Qualifier를 함께 사용하거나, 빈 이름을 명시해야 합니다.
  • 정확한 컨트롤의 어려움: 특정 이름의 빈을 주입하고자 할 때는 @Autowired보다 더 세밀한 제어가 필요함.

사용 예시)

  • 상황: 여러 개의 구현체가 있는 인터페이스를 주입해야 하는 경우, 유연하게 타입만으로 주입할 때 적합하다.
// 두 개의 빈이 있을 경우
@Component
public class ServiceA implements SomeService {
    // 구현체 A
}

@Component
public class ServiceB implements SomeService {
    // 구현체 B
}

@Autowired
private SomeService someService; // 모호할 수 있음

⇒ 같은 타입의 빈이 둘 이상 존재하면 Spring이 어떤 빈을 주입해야 할지 알 수 없으므로 @Qualifier로 명확히 해주어야 한다.

@Autowired
@Qualifier("serviceA")  // 특정 빈을 주입
private SomeService someService;

 

 

결론

  1. 여러 빈이 있을 때 유연성이 필요하다면 @Autowired가 적합하다.
    • 예시: 애플리케이션에 동일한 인터페이스의 여러 구현체가 있지만, 상황에 따라 타입에 맞는 빈을 자동으로 주입하고 싶다면 @Autowired를 사용할 수 있다. 만약 애플리케이션이 확장되거나, 새로운 구현체가 추가되더라도 타입을 기준으로 유연하게 대응할 수 있기 때문이다.
  2. 특정 이름의 빈을 정확히 주입해야 할 때는 @Resource가 적합하다.
    • 예시: 특정 빈을 주입해야 하는 경우, 특히 여러 빈이 동일한 타입을 가지고 있거나, 외부 라이브러리에서 생성된 빈이름을 변경할 수 없는 상황에서 @Resource를 사용하면 정확한 주입을 보장할 수 있다.

요약하자면:

  • 타입 기반으로 유연하게 주입하려면 @Autowired.
  • 특정한 이름의 빈을 정확하게 주입하려면 @Resource.

 

 


참조) 이외, @Inject 라는 애노테이션도 있다.

 

@Inject

: @Autowired와 유사한 기능을 하지만, Java의 표준 DI 애노테이션(JSR-330)이다.

타입을 기준으로 주입하며, Spring 전용이 아닌 애플리케이션에서도 사용 가능하다는 점에서 범용적임

나는 이전 프로젝트에서 autowired 애노테이션을 사용해서 의존성을 주입하였는데, @resource라는 애노테이션을 pms 프로젝트에서 소스분석하다가 발견해서 차이점을 알아보기로 했다.

 

'Web Development > SI 프로젝트' 카테고리의 다른 글

iBatis vs MyBatis  (0) 2024.10.17
휴대폰인증  (0) 2024.09.11
JSP XSS방지  (0) 2024.09.09
임시비밀번호 발급  (0) 2024.07.07
sns 로그인을 위한 정보 yaml 파일에 관리  (0) 2024.07.07