@Resource vs @Autowired


380

DI에서 사용해야하는 @Resource ( jsr250 ) 또는 @Autowired (Spring 관련) 주석은 무엇입니까?

나는 성공적으로 과거에 모두 사용했다 @Resource(name="blah")@Autowired @Qualifier("blah")

내 본능은 @Resource태그가 jsr 사람들에 의해 비준되었으므로 태그 를 고수하는 것입니다.
누구든지 이것에 대해 강한 생각을 가지고 있습니까?


참고- '업데이트'를 제거했는데 별도의 질문으로 표시되어야합니다. 거부 된 의견에 따라 "이 수정 사항은 게시물의 원래 의도와
다릅니다.

답변:


194

봄 3.0 이전에는 어느 것이 중요하지 않습니다.

스프링 3.0 표준 (에 대한 지원이의 JSR-330 ) 주석 @javax.inject.Inject의 조합을 사용하여, - @Qualifier. 스프링은 이제 @javax.inject.Qualifier메타 주석 도 지원합니다 .

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

그래서 당신은 할 수 있습니다

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

또는

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

그리고:

@Inject @YourQualifier private Foo foo;

이로 인해 문자열 이름을 덜 사용하므로 철자가 틀리거나 유지 관리하기가 어렵습니다.


원래 질문에 관해서는 : 주석의 속성을 지정하지 않고 유형별로 주입을 수행하십시오. 차이점은 다음과 같습니다.

  • @Resource 주입 된 Bean의 이름을 지정할 수 있습니다.
  • @Autowired 필수가 아닌 것으로 표시 할 수 있습니다.

이 바보 같은 질문처럼 볼 수 있지만, 당신은 주입이 스타일을 사용하는 경우, 당신이 공공 세터가 필요 할 수도 foo또는 생성자 SomeBeanA를 FooPARAM을?
Snekse

@Snekse-내 대답이 있습니다 : stackoverflow.com/questions/3536674/…
Snekse

아니. 당신은 그 어느 것도 필요하지 않습니다. 필드 만. (봄은 반사를 통해 그것을 채운다)
Bozho

@Bozho이 답변은 실제로 @Resource와 의 차이점을 보여주지 않습니다 @Autowired. 실제 답변은 @Ichthyo 님이 게시 한 것입니다. 업데이트해야합니다.
Boris Treukhov

1
예. 사실 나는 때때로 접근 방식에 대한 더 나은 대안을 제공함으로써 질문에 대답합니다. 그러나 나는 완전성을 위해 아래의 원래 질문에 대한 답을 포함시켰다
Bozho

509

모두 @Autowired(또는 @Inject)와 @Resource작업을 동일하게. 그러나 개념상의 차이 또는 의미의 차이가 있습니다

  • @Resource나에게 이름 으로 알려진 자원을 얻는 것을 의미한다 . 이름은 주석이 달린 세터 또는 필드의 이름에서 추출되거나 name-Parameter에서 가져옵니다.
  • @Inject또는 적합한 다른 구성 요소를 유형별@Autowired 로 배선하십시오 .

기본적으로 이것들은 두 가지 뚜렷한 개념입니다. 불행히도 Spring-Implementation of @Resource의 내장 폴백은 이름 별 해결이 실패 할 때 시작됩니다. 이 경우 @Autowired종류별 종류별 해상도로 돌아갑니다 . 이 대체는 편리하지만 IMHO는 사람들이 개념적 차이를 인식하지 못하고 @Resource유형 기반 자동 배선에 사용하는 경향이 있기 때문에 많은 혼란을 초래합니다 .


81
예, 이것이 받아 들여질만한 답변입니다. 예를 들어 @Resource주석이 달린 필드가 있고 필드 이름이 컨테이너의 빈 ID와 일치하는 org.springframework.beans.factory.BeanNotOfRequiredTypeException경우 스프링 의 유형이 다른 경우 Spring이 throw 됩니다. 이는 빈이 @Resource유형이 아닌 주석의 이름으로 먼저 일치하기 때문 입니다. 그러나 속성 이름이 빈 이름과 일치하지 않으면 Spring은 유형별로 연결합니다.
Boris Treukhov

간단한 MAP을 사용하려고 할 때이 두 가지의 차이점을 알려주는 다른 게시물을 참조 할 수 있습니다. stackoverflow.com/questions/13913752/…
Anver Sadhat

4
허용 된 답변과는 완전히 다른 '모범 사례'를 추천하기보다는 실제로 질문에 답변 한 +1입니다. 또한이 블로그 게시물에서 세 가지 주석 스타일이 모두 포함 된 몇 가지 일반적인 시나리오의 결과를 보여주는 유용한 정보를 제공했습니다. blogs.sourceallies.com/2011/08/…
Jules

1
독자를 위해 여기 @Jules가 지적한 기사의 요약을 찾으십시오. stackoverflow.com/a/23887596/363573
Stephan

3
이것의 한 가지 의미 : 맵 /리스트 빈을 주입하고 싶을 때 @Autowire작동하지 않습니다. 이 경우에 사용해야 @Resource합니다.
Ricardo van den Broek

76

주요 차이점은 @Autowired스프링 주석입니다. @Resource당신이 지적한대로 JSR-250에 의해 지정되는 반면 . 따라서 후자는 Java의 일부이고 전자는 Spring에 고유합니다.

따라서 당신은 어떤 의미에서 그것을 제안하는 것이 옳습니다. 나는 사람들 이 더 강력하기 때문에 @Autowired함께 사용 하는 것을 발견 @Qualifier했습니다. 일부 프레임 워크에서 다른 프레임 워크로 이동하는 것은 신화가 아니라면 특히 봄의 경우에는 매우 가능성이없는 것으로 간주됩니다.


7
때문에 +1, @Autowired@Qualifier정말 입니다 JSR 표준보다 더 강력한 @Resource주석 (와 예를 들어 옵션 종속성 생각 @Autowired(required=false). 당신이 할 수 없어@Resource )
스테판 Haberl

70

나는 하나 개의 코멘트 강조하고 싶은 @Jules을이 답변 이 질문에. 이 주석 에는 @Resource, @Autowired 및 @Inject를 사용한 Spring Injection이 포함되어 있습니다. 나는 당신이 그것을 완전히 읽는 것이 좋습니다, 그러나 여기에 그 유용성의 요약이 있습니다 :

주석이 올바른 구현을 어떻게 선택합니까?

@Autowired@Inject

  1. 유형별 일치
  2. 한정자에 의해 제한
  3. 이름으로 일치

@Resource

  1. 이름으로 일치
  2. 유형별 일치
  3. 한정자에 의해 제한 (이름으로 일치하는 항목은 무시 됨)

콩을 주입 할 때 어떤 주석 (또는 그 조합)을 사용해야합니까?

  1. 구성 요소 이름을 명시 적으로 지정 [@Component ( "beanName")]

  2. [@Resource (name = "beanName")] 속성 @Resource과 함께 사용name

왜 사용하지 않아야 @Qualifier합니까?

@Qualifier유사한 Bean 목록을 작성하지 않으려면 주석을 피하십시오 . 예를 들어 특정 @Qualifier주석 으로 규칙 세트를 표시 할 수 있습니다 . 이 방법을 사용하면 규칙 클래스 그룹을 데이터 처리에 사용할 수있는 목록에 간단하게 삽입 할 수 있습니다.

콩 주입으로 프로그램이 느려 집니까?

구성 요소에 대한 특정 패키지를 스캔하십시오 [context:component-scan base-package="com.sourceallies.person"]. 이것은 더 많은 component-scan구성 을 초래하지만 Spring 컨텍스트에 불필요한 컴포넌트를 추가 할 가능성을 줄입니다.


참조 : @Resource, @Autowired 및 @Inject를 사용한 스프링 주입


39

이것이 Spring 3.0.x Reference Manual 에서 얻은 것입니다 :-

주석 기반 주입을 이름으로 표현하려는 경우 @Qualifier 값을 통해 Bean 이름을 기술적으로 참조 할 수있는 경우에도 @Autowired를 주로 사용하지 마십시오. 대신, JSR-250 @Resource 어노테이션을 사용하십시오. 이는 고유 한 이름으로 특정 대상 컴포넌트를 식별하기 위해 의미 적으로 정의되며, 선언 된 유형은 일치 프로세스와 관련이 없습니다.

이러한 의미 적 차이의 구체적인 결과로, 자체적으로 콜렉션 또는 맵 유형으로 정의 된 Bean은 유형 일치가 적절하게 적용되지 않기 때문에 @Autowired를 통해 삽입 될 수 없습니다. 고유 한 이름으로 특정 콜렉션 또는 맵 Bean을 참조하여 이러한 Bean에 @Resource를 사용하십시오.

@Autowired는 필드, 생성자 및 다중 인수 메서드에 적용되므로 매개 변수 수준에서 한정자 주석을 통해 범위를 좁힐 수 있습니다. 반대로 @Resource는 단일 인수가있는 필드 및 Bean 특성 설정 메소드에만 지원됩니다. 따라서 주입 대상이 생성자 또는 다중 인수 방법 인 경우 한정자를 사용하십시오.


현재 버전은 docs.spring.io/spring/docs/current/spring-framework-reference/…를 참조하십시오 (팁이 업데이트 됨)
Lu55

28

@Autowired + @Qualifier는 나중에 다른 DI를 사용하려는 경우 스프링 DI에서만 작동합니다. @Resource는 좋은 옵션입니다.

@Qualifier는 자리 표시자를 지원하지 않는 반면 @Resource는 잘 수행하므로 @Qualifier는 동적 Bean 배선을 지원하지 않습니다.

예를 들어 다음과 같이 여러 구현이있는 인터페이스가있는 경우

interface parent {

}
@Service("actualService")
class ActualService implements parent{

}
@Service("stubbedService")
class SubbedService implements parent{

}

@Autowired & @Qualifier를 사용하면 다음과 같은 특정 자식 구현을 설정해야합니다

@Autowired
@Qualifier("actualService") or 
@Qualifier("stubbedService") 
Parent object;

@Resource를 사용하는 동안 자리 표시자를 제공하지 않으면 자리 표시자를 넣고 속성 파일을 사용하여 다음과 같은 특정 하위 구현을 주입 할 수 있습니다

@Resource(name="${service.name}")
Parent object;  

여기서 service.name은 특성 파일에서 다음과 같이 설정됩니다.

#service.name=actualService
 service.name=stubbedService

누군가를 돕는 희망 :)


16

둘 다 똑같이 좋습니다. Spring 이외의 다른 DI 프레임 워크를 원한다면 Resource를 사용하는 이점이 있습니다. 코드 변경이 훨씬 간단 해집니다. Autowired를 사용하면 코드가 스프링 DI와 밀접하게 연결됩니다.


17
결코 일어나지 않는. 그리고 그것이 되었더라도-주석 이름에서 찾기 / 바꾸기를 수행하는 것이 가장 적은 문제가 될 것입니다.
Daniel Alexiuc

13

이 두 주석의 기본 클래스에서 비판적으로 분석하면 다음과 같은 차이점이 있습니다.

@AutowiredAutowiredAnnotationBeanPostProcessor 의존성을 주입하는 데 사용 합니다. 의존성을 주입하는
@Resource데 사용 CommonAnnotationBeanPostProcessor합니다.

비록 다른 포스트 프로세서 클래스를 사용하더라도 모두 거의 동일하게 동작합니다. 차이점은 실행 경로에 있으며, 아래에서 강조했습니다.

@Autowired / @Inject

1. 유형별
일치 2. 한정자
별 제한 3. 이름 별 일치

@Resource

1. 이름

일치 2. 유형별 일치 3. 한정자 별 제한 (이름으로 일치하는 항목은 무시 됨)


6

으로 @Resource당신이 콩자가 주사를 할 수있는, 그것은 트랜잭션 또는 보안 관련 물건 같은 콩 포스트 프로세서에 의해 추가 된 모든 추가 로직을 실행하기 위해 필요할 수 있습니다.

Spring 4.3 이상을 사용하면 @Autowired이 작업을 수행 할 수 있습니다.


2

@ResourceJNDI를 통해 정의 된 상위 레벨 오브젝트에서 종종 사용됩니다. @Autowired또는 @Inject더 일반적인 콩에서 사용될 것입니다.

내가 아는 한, 그것은 사양이 아니며 관습이 아닙니다. 표준 코드가 이러한 주석을 사용하는 논리적 인 방법입니다.


0

하십시오 여기에 참고로 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext하고 SpringBeanAutowiringSupport.processInjectionBasedOnServletContext 있지 않음에 와 작업 @Resource 주석. 따라서 차이가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.