DI에서 사용해야하는 @Resource ( jsr250 ) 또는 @Autowired (Spring 관련) 주석은 무엇입니까?
나는 성공적으로 과거에 모두 사용했다 @Resource(name="blah")
및@Autowired @Qualifier("blah")
내 본능은 @Resource
태그가 jsr 사람들에 의해 비준되었으므로 태그 를 고수하는 것입니다.
누구든지 이것에 대해 강한 생각을 가지고 있습니까?
DI에서 사용해야하는 @Resource ( jsr250 ) 또는 @Autowired (Spring 관련) 주석은 무엇입니까?
나는 성공적으로 과거에 모두 사용했다 @Resource(name="blah")
및@Autowired @Qualifier("blah")
내 본능은 @Resource
태그가 jsr 사람들에 의해 비준되었으므로 태그 를 고수하는 것입니다.
누구든지 이것에 대해 강한 생각을 가지고 있습니까?
답변:
봄 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
또는 생성자 SomeBean
A를 Foo
PARAM을?
@Resource
와 의 차이점을 보여주지 않습니다 @Autowired
. 실제 답변은 @Ichthyo 님이 게시 한 것입니다. 업데이트해야합니다.
모두 @Autowired
(또는 @Inject
)와 @Resource
작업을 동일하게. 그러나 개념상의 차이 또는 의미의 차이가 있습니다
@Resource
나에게 이름 으로 알려진 자원을 얻는 것을 의미한다 . 이름은 주석이 달린 세터 또는 필드의 이름에서 추출되거나 name-Parameter에서 가져옵니다.@Inject
또는 적합한 다른 구성 요소를 유형별@Autowired
로 배선하십시오 .기본적으로 이것들은 두 가지 뚜렷한 개념입니다. 불행히도 Spring-Implementation of @Resource
의 내장 폴백은 이름 별 해결이 실패 할 때 시작됩니다. 이 경우 @Autowired
종류별 종류별 해상도로 돌아갑니다 . 이 대체는 편리하지만 IMHO는 사람들이 개념적 차이를 인식하지 못하고 @Resource
유형 기반 자동 배선에 사용하는 경향이 있기 때문에 많은 혼란을 초래합니다 .
@Resource
주석이 달린 필드가 있고 필드 이름이 컨테이너의 빈 ID와 일치하는 org.springframework.beans.factory.BeanNotOfRequiredTypeException
경우 스프링 의 유형이 다른 경우 Spring이 throw 됩니다. 이는 빈이 @Resource
유형이 아닌 주석의 이름으로 먼저 일치하기 때문 입니다. 그러나 속성 이름이 빈 이름과 일치하지 않으면 Spring은 유형별로 연결합니다.
@Autowire
작동하지 않습니다. 이 경우에 사용해야 @Resource
합니다.
주요 차이점은 @Autowired
스프링 주석입니다. @Resource
당신이 지적한대로 JSR-250에 의해 지정되는 반면 . 따라서 후자는 Java의 일부이고 전자는 Spring에 고유합니다.
따라서 당신은 어떤 의미에서 그것을 제안하는 것이 옳습니다. 나는 사람들 이 더 강력하기 때문에 @Autowired
함께 사용 하는 것을 발견 @Qualifier
했습니다. 일부 프레임 워크에서 다른 프레임 워크로 이동하는 것은 신화가 아니라면 특히 봄의 경우에는 매우 가능성이없는 것으로 간주됩니다.
@Autowired
와 @Qualifier
정말 입니다 JSR 표준보다 더 강력한 @Resource
주석 (와 예를 들어 옵션 종속성 생각 @Autowired(required=false)
. 당신이 할 수 없어@Resource
)
나는 하나 개의 코멘트 강조하고 싶은 @Jules을 에 이 답변 이 질문에. 이 주석 에는 @Resource, @Autowired 및 @Inject를 사용한 Spring Injection이 포함되어 있습니다. 나는 당신이 그것을 완전히 읽는 것이 좋습니다, 그러나 여기에 그 유용성의 요약이 있습니다 :
@Autowired
과 @Inject
@Resource
구성 요소 이름을 명시 적으로 지정 [@Component ( "beanName")]
[@Resource (name = "beanName")] 속성 @Resource
과 함께 사용name
@Qualifier
합니까?@Qualifier
유사한 Bean 목록을 작성하지 않으려면 주석을 피하십시오 . 예를 들어 특정 @Qualifier
주석 으로 규칙 세트를 표시 할 수 있습니다 . 이 방법을 사용하면 규칙 클래스 그룹을 데이터 처리에 사용할 수있는 목록에 간단하게 삽입 할 수 있습니다.
구성 요소에 대한 특정 패키지를 스캔하십시오 [context:component-scan base-package="com.sourceallies.person"]
. 이것은 더 많은 component-scan
구성 을 초래하지만 Spring 컨텍스트에 불필요한 컴포넌트를 추가 할 가능성을 줄입니다.
이것이 Spring 3.0.x Reference Manual 에서 얻은 것입니다 :-
팁
주석 기반 주입을 이름으로 표현하려는 경우 @Qualifier 값을 통해 Bean 이름을 기술적으로 참조 할 수있는 경우에도 @Autowired를 주로 사용하지 마십시오. 대신, JSR-250 @Resource 어노테이션을 사용하십시오. 이는 고유 한 이름으로 특정 대상 컴포넌트를 식별하기 위해 의미 적으로 정의되며, 선언 된 유형은 일치 프로세스와 관련이 없습니다.
이러한 의미 적 차이의 구체적인 결과로, 자체적으로 콜렉션 또는 맵 유형으로 정의 된 Bean은 유형 일치가 적절하게 적용되지 않기 때문에 @Autowired를 통해 삽입 될 수 없습니다. 고유 한 이름으로 특정 콜렉션 또는 맵 Bean을 참조하여 이러한 Bean에 @Resource를 사용하십시오.
@Autowired는 필드, 생성자 및 다중 인수 메서드에 적용되므로 매개 변수 수준에서 한정자 주석을 통해 범위를 좁힐 수 있습니다. 반대로 @Resource는 단일 인수가있는 필드 및 Bean 특성 설정 메소드에만 지원됩니다. 따라서 주입 대상이 생성자 또는 다중 인수 방법 인 경우 한정자를 사용하십시오.
@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
누군가를 돕는 희망 :)
둘 다 똑같이 좋습니다. Spring 이외의 다른 DI 프레임 워크를 원한다면 Resource를 사용하는 이점이 있습니다. 코드 변경이 훨씬 간단 해집니다. Autowired를 사용하면 코드가 스프링 DI와 밀접하게 연결됩니다.
이 두 주석의 기본 클래스에서 비판적으로 분석하면 다음과 같은 차이점이 있습니다.
@Autowired
AutowiredAnnotationBeanPostProcessor
의존성을 주입하는 데 사용 합니다. 의존성을 주입하는
@Resource
데 사용 CommonAnnotationBeanPostProcessor
합니다.
비록 다른 포스트 프로세서 클래스를 사용하더라도 모두 거의 동일하게 동작합니다. 차이점은 실행 경로에 있으며, 아래에서 강조했습니다.
@Autowired / @Inject
1. 유형별
일치 2. 한정자
별 제한 3. 이름 별 일치
@Resource
1. 이름
별
일치 2. 유형별 일치 3. 한정자 별 제한 (이름으로 일치하는 항목은 무시 됨)