"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Quarkus에서 합성 콩을 탐색합니다. 강력한 확장 메커니즘

Quarkus에서 합성 콩을 탐색합니다. 강력한 확장 메커니즘

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

Exploring Synthetic Beans in Quarkus. A Powerful Extension Mechanism

Quarkus의 세계에서 종속성 주입 영역은 풍부하고 다양하며 개발자에게 Bean을 관리하고 제어할 수 있는 다양한 도구를 제공합니다. 그러한 도구 중 하나가 합성 콩이라는 개념입니다. 합성 빈은 속성이 Java 클래스, 메소드 또는 필드에서 파생되지 않은 빈을 등록할 수 있게 해주는 강력한 확장 메커니즘입니다. 대신 합성 빈의 모든 속성은 확장으로 정의됩니다.

이 기사에서 우리는 Quarkus의 합성 콩의 세계에 대해 자세히 알아볼 것입니다. 합성 콩의 필요성, 실제 적용 방법, Quarkus 애플리케이션에서 합성 콩을 만들고 사용하는 방법을 살펴보겠습니다.

합성콩의 이해

Quarkus에서 빈은 CDI(컨텍스트 및 종속성 주입) 프레임워크에 의해 관리되는 애플리케이션의 구성 요소입니다. 일반적으로 CDI Bean은 @ApplicationScoped, @RequestScoped 또는 @Inject와 같은 다양한 CDI 주석으로 주석이 달린 Java 클래스입니다. 이 주석
CDI가 빈의 수명주기와 주입을 자동으로 관리할 수 있습니다.

그러나 전통적인 CDI 모델에 딱 들어맞지 않는 빈을 등록해야 하는 상황이 있습니다. 이것은 합성 콩이 작용하는 곳입니다. 합성 빈은 확장에 의해 생성되며 해당 확장에 의해 완전히 정의된 속성을 갖습니다. 일반 CDI 세계에서는 AfterBeanDiscovery.addBean() 및 SyntheticComponents.addBean() 메서드를 사용하여 이를 달성합니다. Quarkus에서는 SyntheticBeanBuildItem을 사용하여 이 작업을 수행합니다.

언제 합성 콩이 필요합니까?

그럼 언제 Quarkus에서 합성빈을 사용해야 할까요? 합성콩은 다음과 같은 경우에 강력한 도구입니다:

  1. 타사 라이브러리 통합: CDI 주석이 없지만 CDI 기반 애플리케이션에 통합해야 하는 타사 라이브러리로 작업하고 있습니다. 합성콩을 사용하면 이러한 격차를 해소할 수 있습니다.

  2. 동적 Bean 등록: 구성이나 기타 요인에 따라 런타임에 Bean을 동적으로 등록해야 합니다. 합성 콩을 사용하면 즉시 콩을 생성하고 등록할 수 있는 유연성을 얻을 수 있습니다.

  3. 사용자 정의 Bean 관리: 표준 CDI 주석으로는 달성할 수 없는 Bean의 범위와 동작을 세밀하게 제어해야 합니다.

  4. 특수 Bean 구현: 기존 Java 클래스 또는 메소드에 해당하지 않는 고유 속성을 가진 특수 Bean을 생성하려고 합니다.

  5. 테스트를 위한 모의 종속성: 합성 빈은 테스트 목적으로 종속성을 모의하고 모의 구현을 주입하는 유용한 방법을 제공합니다.

합성완료빌드아이템

SynesisFinishedBuildItem은 CDI Bean 검색 및 등록 프로세스가 완료되었음을 나타내는 데 사용됩니다. 이를 통해 확장 프로그램은 등록된 Bean과 상호 작용하는 것이 안전한 시기를 알 수 있습니다.

예를 들어:

@BuildStep  
void onSynthesisFinished(SynthesisFinishedBuildItem synthesisFinished){
    // CDI bean registration is complete, can now safely interact with beans
    }

SyntheticBeansRuntimeInitBuildItem

SyntheticBeansRuntimeInitBuildItem은 모든 합성 빈이 초기화된 후 런타임에 호출될 콜백을 등록하는 데 사용됩니다. 이는 합성 Bean과 관련된 추가 초기화 로직을 수행해야 하는 경우 유용합니다.

예를 들어:

@BuildStep
SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){

    return new SyntheticBeansRuntimeInitBuildItem(ids->{
    // Perform logic with initialized synthetic beans
    });

    }

SyntheticBeansRuntimeInitBuildItem에 전달된 콜백은 초기화된 모든 합성 빈의 ID가 포함된 Set를 수신합니다.

요약하면 SynesisFinishedBuildItem은 빈 검색이 완료되었음을 나타내는 반면 SyntheticBeansRuntimeInitBuildItem은 합성 빈에 따라 로직 초기화를 허용합니다.

SyntheticBeanBuildItem을 사용하여 합성 콩 생성

Quarkus에서는 SyntheticBeanBuildItem 클래스 덕분에 합성 빈을 생성하는 과정이 간단해졌습니다. 합성 빈을 생성하고 사용하는 단계를 살펴보겠습니다.

  1. 합성 콩 클래스 생성: 합성 콩 클래스를 정의하는 것부터 시작합니다. 이 클래스는 합성 빈의 기초가 될 것입니다.
package com.iqnev;

public class MySyntheticBean {

  // Define the behavior and attributes of your synthetic bean
  public void printMessage() {
    System.out.println("Hello from synthetic bean!");
  }
}
  1. Quarkus 확장 생성: 합성 빈을 등록하려면 Quarkus 확장을 생성해야 합니다. 이 확장 클래스는 SyntheticBeanBuildItem을 사용하여 Bean을 구성합니다.

바이트코드 생성 접근 방식

package com.iqnev;

import io.quarkus.arc.deployment.SyntheticBeanBuildItem;

public class MySyntheticBeanExtension {

  @BuildStep
  SyntheticBeanBuildItem syntheticBean() {
    return SyntheticBeanBuildItem
        .configure(MySyntheticBean.class)
        .scope(ApplicationScoped.class)
        .creator(mc -> {
          mc.returnValue(new MySyntheticBean());
        })
        .done();
  }
}

SyntheticBeanBuildItem의 .creator() 메서드는 런타임에 합성 Bean의 인스턴스를 생성하는 바이트코드를 생성하는 데 사용됩니다.

.creator()에 전달된 인수는 메소드 내에서 Java 바이트코드를 생성할 수 있는 Consumer입니다.

이 예에서는:

  1. mc는 MethodCreator 인스턴스입니다
  2. mc.returnValue(new MySyntheticBean())은 바이트코드를 생성하여 MySyntheticBean의 새 인스턴스를 생성하고 이를 메서드에서 반환합니다.

따라서 본질적으로 우리는 Quarkus에게 다음과 같은 메소드를 생성하라고 지시합니다:

MySyntheticBean createSyntheticBean(){
    return new MySyntheticBean();
    }

이 생성된 메소드는 주입되거나 사용되어야 할 때 MySyntheticBean을 인스턴스화하기 위해 호출됩니다.

바이트코드 생성을 사용하는 이유는 합성 빈이 실제 Java 클래스/메서드와 일치하지 않기 때문에 이를 인스턴스화하기 위한 메서드를 명시적으로 생성해야 하기 때문입니다.

SyntheticBeanBuildItem의 출력은 빌드 시 기록된 바이트코드입니다. 이는 런타임 시 인스턴스가 생성되는 방식을 제한합니다. 일반적인 옵션은 다음과 같습니다:

  1. .creator()를 통해 직접 바이트코드 생성
  2. BeanCreator 하위 클래스 사용
  3. @Recorder 메소드를 통해 인스턴스 생성

레코더 접근 방식

@Record 및 .runtimeValue() 접근 방식은 Quarkus에서 합성 Bean에 대한 인스턴스를 제공하는 대체 방법입니다.

이를 사용하면 @Record(STATIC_INIT) 주석이 달린 레코더 클래스 메소드를 통해 합성 Bean을 인스턴스화할 수 있습니다.

예를 들어:

@Recorder
public class MyRecorder {

  @Record(STATIC_INIT)
  public MySyntheticBean createBean() {
    return new MySyntheticBean();
  }

}

  @BuildStep
  SyntheticBeanBuildItem syntheticBean(MyRecorder recorder) {
    return SyntheticBeanBuildItem
        .configure(MySyntheticBean.class)
        .runtimeValue(recorder.createBean());
  }

여기서 .runtimeValue()는 빈을 인스턴스화하기 위해 레코더 메소드를 참조합니다. 이를 통해 RuntimeValue를 직접 전달하여 합성 Bean 인스턴스를 제공할 수 있습니다.

예를 들어:

@BuildStep 
SyntheticBeanBuildItem syntheticBean(){

    RuntimeValue bean= //...

    return SyntheticBeanBuildItem
    .configure(MySyntheticBean.class)
    .runtimeValue(bean);

    }

RuntimeValue는 기록자, 공급자, 프록시 등에서 나올 수 있습니다.

요약하자면:

  • @Record는 RuntimeValue를 생성하는 한 가지 접근 방식입니다.
  • .runtimeValue()는 SyntheticBeanBuildItem에 RuntimeValue를 설정합니다.

둘 다 약간 다른 방식으로 런타임 인스턴스 제공이라는 동일한 목표를 달성합니다.

Quarkus에서 합성 빈에 대한 런타임 인스턴스를 제공할 때 바이트코드를 직접 생성하는 것보다 더 발전된 접근 방식으로 레코더를 사용하는 것을 고려하겠습니다(@Record를 통해).
.creator()를 사용하거나 간단한 RuntimeValues를 제공합니다.

녹음기 사용이 더욱 발전될 수 있는 몇 가지 이유는 다음과 같습니다.

  • 추가 캡슐화 - Bean을 인스턴스화하는 논리는 빌드 단계에 직접 포함되지 않고 별도의 레코더 클래스에 포함됩니다. 이렇게 하면 빌드 단계가 간결해집니다.
  • 재사용 - 작성자 로직을 다시 작성하는 대신 레코더 메소드를 여러 합성 Bean에서 재사용할 수 있습니다.
  • 런타임 데이터 - 레코더 메소드는 런타임에 실행되므로 런타임 리소스, 구성, 서비스 등을 활용하여 Bean을 구성할 수 있습니다.
  • 종속성 주입 - 레코더 메서드에서 다른 서비스를 주입할 수 있습니다.
  • 라이프 사이클 제어 - @Record(STATIC_INIT) 또는 @Record(RUNTIME_INIT)로 주석이 달린 레코더 메서드는 Bean 인스턴스화 라이프 사이클을 더 효과적으로 제어할 수 있습니다.
  • 관리 빈 - 레코더 내부에서 인스턴스화된 빈은 그 자체로 CDI 관리 빈이 될 수 있습니다.

요약하자면 레코더 메서드는 합성 빈 인스턴스화를 위해 더 많은 캡슐화, 유연성, 런타임 데이터 및 서비스에 대한 액세스를 제공합니다. 직접 바이트코드 생성에 비해 더 발전된 빈 생성 로직을 허용합니다.

그러나 .creator()를 사용한 직접 바이트코드 생성은 레코더가 과도할 수 있는 간단한 경우에 여전히 유용할 수 있습니다. 그러나 합성콩 수요가 증가함에 따라 레코더는 더욱 강력해지고
고급 접근 방식.

기본 STATIC_INIT 단계 대신 RUNTIME_INIT 단계 중에 초기화되도록 Quarkus의 합성 빈을 구성할 수 있습니다.

예는 다음과 같습니다.

@BuildStep
@Record(RUNTIME_INIT)
SyntheticBeanBuildItem lazyBean(BeanRecorder recorder){

    return SyntheticBeanBuildItem
    .configure(MyLazyBean.class)
    .setRuntimeInit() // initialize during RUNTIME_INIT
    .runtimeValue(recorder.createLazyBean());

    }

핵심 사항은 다음과 같습니다.

  • SyntheticBeanBuildItem에서 setRuntimeInit()를 사용하여 RUNTIME_INIT로 표시합니다.
  • 레코더 메소드에는 @Record(RUNTIME_INIT) 주석을 달아야 합니다.
  • STATIC_INIT 중에는 런타임 초기화 합성 Bean에 액세스할 수 없습니다.

요약하자면, 열성적인 STATIC_INIT 인스턴스화가 필요하지 않은 경우 합성 빈은 RUNTIME_INIT 중에 느리게 초기화될 수 있습니다. 이를 통해 시작 시간을 최적화할 수 있습니다.

합성 빈 사용: 이제 합성 빈이 등록되었으므로 이를 애플리케이션에 주입하여 사용할 수 있습니다.

package com.iqnev;

import javax.inject.Inject;

public class MyBeanUser {

  @Inject
  MySyntheticBean mySyntheticBean;

  public void useSyntheticBean() {
    // Use the synthetic bean in your code
    mySyntheticBean.printMessage();
  }
}

애플리케이션 실행: 평소처럼 Quarkus 애플리케이션을 빌드하고 실행하면 합성 빈을 주입하고 사용할 수 있습니다.

결론

Quarkus의 합성 Bean은 외부 라이브러리를 통합하고, Bean을 동적으로 등록하고, CDI 기반 애플리케이션에서 Bean 동작을 사용자 정의하기 위한 강력한 메커니즘을 제공합니다. Java 클래스가 아닌 확장으로 속성이 정의되는 이러한 Bean은 종속성 관리에 유연성과 다양성을 제공합니다.

이 기사에서 살펴본 것처럼 Quarkus에서 합성 콩을 만들고 사용하는 과정은 간단합니다. SyntheticBeanBuildItem 및 Quarkus 확장을 활용하면 기존 CDI와 보다 전문적이거나 동적인 Bean 등록 요구 사항 간의 격차를 원활하게 메울 수 있습니다.

계속 진화하는 Java 프레임워크 환경에서 Quarkus는 합성 빈과 같은 혁신적인 솔루션을 제공함으로써 계속해서 두각을 나타내고 있으며 현대적이고 효율적이며 유연한 애플리케이션 개발을 위한 강력한 선택입니다. Quarkus에서 합성 빈의 힘을 활용하고 종속성 주입을 한 단계 더 발전시키세요!

릴리스 선언문 이 기사는 https://dev.to/yanev/exploring-synthetic-beans-in-quarkus-a-powerful-extension-mechanism-fbd?1에서 복제됩니다. 침해가 있는 경우, [email protected]으로 문의해 주십시오. 그것을 삭제하려면
최신 튜토리얼 더>

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

Copyright© 2022 湘ICP备2022001581号-3