Quarkus Extension - Additional Bean Build Item

After discussing the ApplicationIndexBuildItem and CombinedIndexBuildItem, let’s continue exploring Quarkus build items with the AdditionalBeanBuildItem. This build item is part of the configuration items for the Arc library , which handles dependency injection in Quarkus.

Quarkus and Dependency Injection

Quarkus heavily relies on dependency injection, allowing for loose coupling between different objects in a Quarkus application. Quarkus uses a library called Arc that automatically scans the application’s classpath and references all classes declared as beans (e.g., those annotated with @Controller, @Service, etc.) for injection.

In an extension, it may be beneficial to declare objects provided by the extension as beans to make them injectable. An extension might also need to declare objects from the target application or its dependencies as injectable beans, even if they are not annotated with a Quarkus-recognized annotation. This is where AdditionalBeanBuildItem comes into play.

AdditionalBeanBuildItem

This build item is very simple to use in its most basic form, taking the class to be declared as a bean as a parameter.

1
2
3
4
5
6
@BuildStep()
void addBeans(BuildProducer<AdditionalBeanBuildItem> producer) {
    producer.produce(new AdditionalBeanBuildItem("my.package.Foo"));
    // or
    producer.produce(new AdditionalBeanBuildItem(Foo.class));
}

It is often combined with another BuildItem (e.g., CombinedIndexBuildItem) to retrieve the classes to be declared as beans.

By default, only the beans detected as used during the Quarkus build will be retained. This can be configured as follows:

1
2
3
4
5
6
7
8
9
@BuildStep()
void addBeans(BuildProducer<AdditionalBeanBuildItem> producer) {
    producer.produce(AdditionalBeanBuildItem.unremovableOf("my.package.Foo"));
    // or

    producer.produce(AdditionalBeanBuildItem.Builder()
            .addBeanClasses(Foo.class)
            .setUnremovable()); // Will not be removed if not link during compiled time (e.g: Used with reflection)
}

The bean’s scope can also be specified as follows if the class does not specify a scope. According to the documentation, this method should only be used if no annotation can be directly applied to the target class.

1
2
3
4
5
6
7
@BuildStep()
void addBeans(BuildProducer<AdditionalBeanBuildItem> producer) {
    producer.produce(AdditionalBeanBuildItem.Builder()
            .addBeanClasses(Foo.class)
            .setUnremovable()
            .setDefaultScope(DotNames.APPLICATION_SCOPED));
}

Conclusion

The AdditionalBeanBuildItem is a widely used build item by Quarkus extensions to make their beans injectable in applications using these extensions. The second use case is to make objects from third-party libraries, which are not declared as beans, injectable.

0%