No mundo do Quarkus, o domínio da injeção de dependência é rico e versátil, oferecendo aos desenvolvedores uma infinidade de ferramentas para gerenciar e controlar beans. Uma dessas ferramentas é o conceito de feijão sintético. Os beans sintéticos são um poderoso mecanismo de extensão que permite registrar beans cujos atributos não são derivados de uma classe, método ou campo Java. Em vez disso, todos os atributos de um bean sintético são definidos por uma extensão.
Neste artigo, vamos nos aprofundar no mundo dos feijões sintéticos no Quarkus. Exploraremos a necessidade dos feijões sintéticos, suas aplicações práticas e como criá-los e usá-los em suas aplicações Quarkus.
No Quarkus, os beans são os blocos de construção da sua aplicação, gerenciados pela estrutura Contexts and Dependency Injection (CDI). Normalmente, os beans CDI são classes Java anotadas com várias anotações CDI, como @ApplicationScoped, @RequestScoped ou @Inject. Essas anotações
permitir que o CDI gerencie automaticamente o ciclo de vida e a injeção de beans.
No entanto, há situações em que você pode precisar registrar um bean que não se encaixa perfeitamente no modelo CDI tradicional. É aqui que entra o feijão sintético. Os beans sintéticos são criados por extensões e têm seus atributos totalmente definidos por essas extensões. No mundo do CDI normal, você conseguiria isso usando os métodos AfterBeanDiscovery.addBean() e SyntheticComponents.addBean(). No Quarkus, isso é feito usando SyntheticBeanBuildItem.
Então, quando você pode precisar usar feijões sintéticos no Quarkus? Os feijões sintéticos são uma ferramenta poderosa quando:
Integração de bibliotecas de terceiros: Você está trabalhando com uma biblioteca de terceiros que não possui anotações de CDI, mas precisa ser integrada ao seu aplicativo baseado em CDI. Os feijões sintéticos permitem preencher essa lacuna.
Registro Dinâmico de Bean: Você precisa registrar beans dinamicamente em tempo de execução, dependendo da configuração ou de outros fatores. Os feijões sintéticos oferecem flexibilidade para criar e registrar feijões dinamicamente.
Gerenciamento de Bean Personalizado: Você precisa de um controle refinado sobre o escopo e o comportamento de um bean que não pode ser alcançado com anotações CDI padrão.
Implementando Beans Especializados: Você deseja criar beans especializados com atributos exclusivos que não correspondem às classes ou métodos Java tradicionais.
Mocking Dependency for Testing: Os beans sintéticos fornecem uma maneira útil de simular dependências e injetar implementações simuladas para fins de teste.
O SynthesisFinishedBuildItem é usado para indicar que o processo de descoberta e registro do bean CDI foi concluído. Isso permite que as extensões saibam quando é seguro interagir com os beans que foram registrados.
Por exemplo:
@BuildStep void onSynthesisFinished(SynthesisFinishedBuildItem synthesisFinished){ // CDI bean registration is complete, can now safely interact with beans }
O SyntheticBeansRuntimeInitBuildItem é usado para registrar um retorno de chamada que será invocado em tempo de execução após todos os beans sintéticos terem sido inicializados. Isso é útil se você precisar executar lógica de inicialização adicional envolvendo beans sintéticos.
Por exemplo:
@BuildStep SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){ return new SyntheticBeansRuntimeInitBuildItem(ids->{ // Perform logic with initialized synthetic beans }); }
O retorno de chamada passado para SyntheticBeansRuntimeInitBuildItem receberá um Set
Então, em resumo, SynthesisFinishedBuildItem indica que a descoberta do bean foi concluída, enquanto SyntheticBeansRuntimeInitBuildItem permite inicializar a lógica dependendo dos beans sintéticos.
No Quarkus, criar beans sintéticos é um processo simples, graças à classe SyntheticBeanBuildItem. Vamos seguir as etapas para criar e usar um bean sintético:
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!"); } }
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(); } }
O método .creator() em SyntheticBeanBuildItem é usado para gerar o bytecode que criará instâncias do bean sintético em tempo de execução.
O argumento passado para .creator() é um Consumer
Neste exemplo:
Então, essencialmente, estamos dizendo ao Quarkus para gerar um método parecido com:
MySyntheticBean createSyntheticBean(){ return new MySyntheticBean(); }
Este método gerado será então chamado para instanciar o MySyntheticBean quando ele precisar ser injetado ou usado.
A razão pela qual a geração de bytecode é usada é que os beans sintéticos não correspondem a classes/métodos Java reais, então temos que gerar explicitamente um método para instanciá-los
A saída de SyntheticBeanBuildItem é um bytecode registrado no momento da construção. Isso limita como as instâncias são criadas em tempo de execução. As opções comuns são:
As abordagens @Record e .runtimeValue() são formas alternativas de fornecer instâncias para beans sintéticos no Quarkus.
Isso permite instanciar o bean sintético por meio de um método de classe de gravador anotado com @Record(STATIC_INIT).
Por exemplo:
@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()); }
Aqui o .runtimeValue() faz referência ao método recorder para instanciar o bean. Isso permite passar um RuntimeValue diretamente para fornecer a instância do bean sintético.
Por exemplo:
@BuildStep SyntheticBeanBuildItem syntheticBean(){ RuntimeValuebean= //... return SyntheticBeanBuildItem .configure(MySyntheticBean.class) .runtimeValue(bean); }
O RuntimeValue pode vir de um gravador, fornecedor, proxy etc.
Então, em resumo:
Ambos atingem o mesmo objetivo de fornecer uma instância de tempo de execução, apenas de maneiras ligeiramente diferentes.
Quando se trata de fornecer instâncias de tempo de execução para beans sintéticos no Quarkus, eu consideraria o uso de gravadores (via @Record) como uma abordagem mais avançada em comparação à geração direta de bytecode
com .creator() ou fornecendo RuntimeValues simples.
Aqui estão alguns motivos pelos quais o uso de gravadores pode ser mais avançado:
Então, em resumo, os métodos de gravador fornecem mais encapsulamento, flexibilidade e acesso a dados e serviços de tempo de execução para instanciar beans sintéticos. Eles permitem uma lógica de produção de bean mais avançada em comparação com a geração direta de bytecode.
No entanto, a geração direta de bytecode com .creator() ainda pode ser útil para casos simples em que os gravadores podem ser um exagero. Mas à medida que as necessidades de feijão sintético aumentam, os gravadores são mais poderosos e
abordagem avançada.
É possível configurar um bean sintético no Quarkus para ser inicializado durante a fase RUNTIME_INIT em vez da fase STATIC_INIT padrão.
Aqui está um exemplo:
@BuildStep @Record(RUNTIME_INIT) SyntheticBeanBuildItem lazyBean(BeanRecorder recorder){ return SyntheticBeanBuildItem .configure(MyLazyBean.class) .setRuntimeInit() // initialize during RUNTIME_INIT .runtimeValue(recorder.createLazyBean()); }
Os pontos principais são:
Portanto, em resumo, os beans sintéticos podem ser inicializados lentamente durante RUNTIME_INIT para casos em que a instanciação antecipada de STATIC_INIT não é necessária. Isso permite otimizar o tempo de inicialização.
Usar o Feijão Sintético: Agora que seu feijão sintético está registrado, você pode injetá-lo e utilizá-lo em sua aplicação.
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(); } }
Executando seu aplicativo: Crie e execute seu aplicativo Quarkus normalmente, e o bean sintético estará disponível para injeção e uso.
Beans sintéticos no Quarkus fornecem um mecanismo poderoso para integrar bibliotecas externas, registrar beans dinamicamente e personalizar o comportamento do bean em seus aplicativos baseados em CDI. Esses beans, cujos atributos são definidos por extensões em vez de classes Java, oferecem flexibilidade e versatilidade no gerenciamento de dependências.
Como exploramos neste artigo, criar e usar beans sintéticos no Quarkus é um processo simples. Ao aproveitar as extensões SyntheticBeanBuildItem e Quarkus, você pode preencher perfeitamente a lacuna entre o CDI tradicional e os requisitos de registro de beans mais especializados ou dinâmicos.
No cenário em constante evolução das estruturas Java, a Quarkus continua a se destacar por oferecer soluções inovadoras como beans sintéticos, tornando-se uma escolha atraente para o desenvolvimento de aplicações modernas, eficientes e flexíveis. Aproveite o poder dos feijões sintéticos no Quarkus e leve sua injeção de dependência para o próximo nível!
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3