"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > @Named를 통한 도전과제 공개

@Named를 통한 도전과제 공개

2024-09-02에 게시됨
검색:979

끊임없이 진화하는 컨텍스트 및 종속성 주입(CDI) 환경에서 개발자는 Bean 이름 지정, 기본 구현 및 잠재적 충돌과 관련된 장애물에 자주 직면합니다. 이 문서에서는 CDI의 @Named 주석과 관련된 잠재적 위험에 대한 자세한 탐색을 제공합니다. 우리는 그 복잡성을 조사하고, 문제가 있는 시나리오를 밝히고, SmallRye의 @Identifier 사용을 포함한 대체 접근 방식에 대해 논의할 것입니다. 또한 강력하고 유지 관리가 가능한 자카르타 EE
를 구축하기 위한 모범 사례에 대한 통찰력을 제공할 것입니다. 응용 프로그램.

@기본 이해

@Default 주석은 특정 구현을 특정 인터페이스 또는 Bean 유형의 기본 구현으로 명시적으로 표시하기 위한 CDI의 유용한 도구입니다. 이는 동일한 인터페이스의 여러 구현을 처리할 때 작동하므로 개발자는 다른 한정자를 사용하지 않을 때 기본적으로 어떤 구현을 주입해야 하는지 지정할 수 있습니다.

GreetingService 인터페이스의 여러 구현이 존재하는 시나리오를 고려해보세요.

@Default
public class DefaultGreetingService implements GreetingService {

  @Override
  public String greet(String name) {
    return "Hello, "   name;
  }
}
public class SpecialGreetingService implements GreetingService {

  @Override
  public String greet(String name) {
    return "Greetings, "   name   "!";
  }
}

한정자를 지정하지 않고 Bean을 주입하는 경우 CDI는 @Default 표시가 있는 Bean을 기본값으로 사용합니다. 이는 여러 구현이 포함된 시나리오에 유용하며 명확한 기본 선택을 제공합니다.

@Inject
private GreetingService greetingService; // Injects the @Default implementation

@Default 사용은 선택 사항이지만 특히 여러 구현이 있는 인터페이스를 처리할 때 사용하는 것이 좋습니다. 명확하고 일관된 기본 옵션을 제공하여 Bean 주입 중 모호함과 예상치 못한 동작을 방지합니다.

@Named 탐색 - 양날의 검

@Named 한정자는 CDI에서 기본적인 역할을 수행하여 사람이 읽을 수 있는 이름이나 식별자를 Bean에 할당합니다. 개발자들은 빈을 다른 컴포넌트에 주입할 때 빈을 이름으로 참조하기 위해 종종 이를 사용합니다.

그러나 @Named에는 특히 추가 한정자 없이 사용할 때 자체적인 문제가 있습니다. 기본적으로 CDI는 규정되지 않은 클래스 이름을 Bean 이름과 연관시킵니다. 이로 인해 @Default 한정자와 충돌이 발생하여 Bean 주입 중에 예기치 않은 동작이 발생할 수 있습니다.

@Named
public class MyBean {
  // Implementation
}

명시적인 한정자 없이 MyBean을 주입하는 경우 CDI는 @Default 한정자가 아닌 @Named 한정자만 추가합니다. @Default 한정자는 Bean 또는 해당 한정자에 명시적으로 지정된 경우에만 적용됩니다.

@Inject
private MyBean myBean;

이 경우, 같은 타입명을 가진 다른 Bean이 있으면 모호성이 발생할 수 있습니다. 예를 들어 MyBean이라는 또 다른 Bean이 있는 경우 주입으로 인해 모호성이 발생합니다.

이 문제를 해결하려면 개발자는 주입하려는 Bean을 명시적으로 한정해야 합니다.

@Inject
@Named("myBean")
private MyBean myBean;

또는 개발자는 모호성을 제거하기 위해 각 Bean에 대한 사용자 정의 한정자를 활용할 수 있습니다.

문제가 있는 경우: 모호함 및 의도하지 않은 기본값

추가 한정자 없이 @Named를 사용하고 동일한 유형의 구현이 여러 개 존재하는 경우 모호성이 발생합니다. 다음 시나리오를 고려해보세요.

@Named
public class ServiceA implements Service {
  // Implementation
}
@Named
public class ServiceB implements Service {
  // Implementation
}

명시적인 한정자 없이 서비스를 주입하면 두 Bean이 유형별로 일치하고 이름이나 한정자가 구별되지 않으므로 모호성이 발생할 수 있습니다.

@Inject
private Service service;

이 경우 CDI는 @Default를 암시적으로 추가하지 않거나 모호성을 해결하려고 시도하지 않아 모호한 종속성으로 인해 주입이 실패합니다.

대안: SmallRye Common의 @Identifier 소개

@Named가 제기한 문제를 인식하여 개발자는 종종 Bean 식별에 대한 보다 명시적인 제어를 위한 대안을 모색합니다. 그러한 대안 중 하나는
의 @Identifier 주석입니다. 스몰라이 커먼. 이 주석은 Bean 이름 지정에 대한 보다 명확하고 제어된 접근 방식을 제공하여 충돌 및 예상치 못한 기본값의 위험을 줄입니다. 각 애플리케이션에 고유한 값이 필요한 @Named와 달리 @Identifier는 유형이 다른 한 동일한 식별자 값을 가진 여러 Bean을 허용합니다. 이러한 유연성은 동일한 인터페이스나 관련 유형의 다양한 구현을 처리할 때 특히 유용합니다.

@Identifier를 사용하려면 빈 클래스에 주석을 추가하고 식별자 값을 지정하세요.

@Identifier("payment")
public class DefaultPaymentProcessor implements PaymentProcessor {
  // Implementation
}
@Identifier("payment")
public class LegacyPaymentGateway implements PaymentGateway {
  // Implementation
}

@Identifier를 사용하여 Bean을 주입하는 것은 간단합니다.

public class Client {
  @Inject
  @Identifier("payment")
  PaymentProcessor processor;

  @Inject
  @Identifier("payment")
  PaymentGateway gateway;

}

여기에서 PaymentProcessor와 PaymentGateway 유형이 다르기 때문에 "결제" @Identifier 값이 여러 Bean에 재사용됩니다. 이러한 유연성은 @Named에서는 허용되지 않습니다. 여기서
값은 애플리케이션 전체에서 고유해야 합니다.

@Named의 또 다른 대안은 사용자 정의 한정자를 만드는 것입니다. 사용자 정의 한정자는 Bean을 식별하고 한정하는 데 사용할 수 있는 사용자 정의 주석입니다. 이는 빈 선택에 대한 가장 세부적인 제어를 제공하며 애플리케이션의 특정 요구 사항에 맞게 조정할 수 있습니다.

맞춤 한정자를 만들려면 다음 단계를 따르세요.

  1. 새 주석 클래스를 정의합니다.
  2. @Qualifier로 주석 클래스에 주석을 답니다.
  3. 선택적으로 한정자의 기본값을 제공합니다.

예를 들어, DefaultPaymentGateway라는 다음 사용자 정의 한정자는 기본 결제 게이트웨이 구현을 나타냅니다.

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface DefaultPaymentGateway {

}

사용자 정의 한정자를 사용하려면 다음과 같이 Bean 클래스에 주석을 답니다.

@DefaultPaymentGateway
public class StandardPaymentGateway implements PaymentGateway {
  // Implementation
}
public class ExpressPaymentGateway implements PaymentGateway {
  // Implementation
}

그런 다음 한정자를 사용하여 빈을 주입합니다.

@Inject
@DefaultPaymentGateway
private PaymentGateway paymentGateway;

올바른 접근 방식 선택

빈 식별을 위한 최선의 접근 방식은 애플리케이션의 특정 요구 사항에 따라 다릅니다. 간단한 애플리케이션의 경우 @Named로 충분할 수 있습니다. 더 복잡한 애플리케이션의 경우 @Identifier 또는
사용자 정의 한정자는 더 많은 제어와 유연성을 제공합니다.

다음 표에는 각 접근 방식의 장단점이 요약되어 있습니다.

접근하다 장점 단점
@이름이 지정됨 간단하고 널리 지원됨 모호할 수 있으며 @Default와 충돌합니다.
@식별자 더 명확한 식별, @Default와 충돌 없음 추가 주석이 필요합니다.
맞춤 한정자 최대한의 유연성, 세밀한 제어 정의하고 유지 관리하려면 사전 노력이 필요합니다.

자세한 확인은 공식 CDI 사양

을 참조하세요.

Unveiling Challenges with @Named

결론: 빈 이름 지정 및 기본값에 대한 전략적 선택

결론적으로 @Named와 관련된 잠재적 위험은 CDI에서 이 주석을 사용할 때 신중하게 고려해야 한다는 점을 강조합니다. 특히 여러 구현이 있는 경우 암시적 이름 지정에 의존할 때 모호함과 의도하지 않은 기본값이 발생할 수 있습니다. 개발자는 Bean 식별에 대한 보다 제어되고 명시적인 접근 방식을 위해 SmallRye Common의 @Identifier와 같은 대안을 탐색하는 것이 좋습니다. 명시적 자격, 사용자 정의 한정자 및 대체 접근 방식을 수용하면 보다 원활하고 제어된 CDI 환경이 보장되어 강력하고 유지 관리가 가능한 Java가 탄생합니다.

릴리스 선언문 이 기사는 https://dev.to/yanev/unveiling-challenges-with-named-67p?1에서 복제됩니다.1 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3