Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register bean programatically in Quarkus?

Tags:

quarkus

I am trying to find a way how to programatically create bean in quarkus DI, but without success. Is it possible in this framework? It seems that BeanManager does not implement the needed method yet.

like image 875
Mejmo Avatar asked Apr 28 '20 21:04

Mejmo


People also ask

What is CDI Quarkus?

Quarkus ArC is a build-time oriented dependency injection based on CDI 2.0. In this blogpost, we're going to explain the relationship to the specification and describe some of the benefits and drawbacks of the build-time processing design.

Does Quarkus use reflection?

Quarkus makes registration of reflection in an extension a breeze by using ReflectiveClassBuildItem , thus eliminating the need for a JSON configuration file.

What is not Proxyable because it has no no args constructor?

Config is not proxyable because it has no no-args constructor - Managed Bean [class xx. Config] with qualifiers [@Default @Named @Any]. The possible reason for this is that a non-dependent scoped bean is required to provide a public no-args constructor for CDI, so that it can pick up the desired proxy bean at runtime.


2 Answers

First, we should clarify what "programatically create bean" exactly means.

But first of all, we should define what "bean" means. In CDI, we talk about beans in two meanings:

  1. Component metadata - this one describes the component attributes and how a component instance is created; the SPI is javax.enterprise.inject.spi.Bean
  2. Component instance - the real instance used in application; in the spec we call it "contextual reference".

The metadata is usually derived from the application classes. Such metadata are "backed by a class". By "backed by a class" I mean all the kinds described in the spec. That is class beans, producer methods and producer fields.

Now, if you want to programatically obtain a component instance (option 2), you can:

  1. Inject javax.enterprise.inject.Instance; see for example the Weld docs
  2. Make use of CDI.current().select(Foo.class).get()
  3. Make use of quarkus-specific Arc.container().instance(Foo.class).get()

However, if you want to add/register a component metadata that is not backed by a class (option 2), you need to add an extension that makes use of quarkus-specific SPIs, such as BeanRegistrar.

like image 107
Martin Kouba Avatar answered Sep 29 '22 13:09

Martin Kouba


If you are looking for Quarkus equivalent of Spring @Configuration then you want "bean producer" (as mentioned in comments above)

Here is an example(koltin) of how to manually register a clock:

import java.time.Clock
import javax.enterprise.context.ApplicationScoped
import javax.enterprise.inject.Produces

@ApplicationScoped
class AppConfig {

   @Produces
   @ApplicationScoped
   fun utcClock(): Clock {
       return Clock.systemUTC()
   }  
}
  • @Produces is actually not required if method is already annotated with @ApplicationScoped
  • @ApplicationScoped at class level of AppConfig is also not required

Although, I find those extra annotations useful, especially if are used to Spring.

like image 40
rozky Avatar answered Sep 29 '22 13:09

rozky