Build time CDI dependency injection framework for Quarkus applications with conditional bean support and context management
—
Enable beans based on build-time configuration properties, allowing feature toggles and environment-specific configurations. These annotations evaluate property values during the build process to determine bean inclusion.
Enables beans when build-time properties match specified values.
/**
* When applied to a bean class or producer method (or field), the bean will only be enabled
* if the Quarkus build time property matches the provided value.
* By default, the bean is not enabled when the build time property is not defined at all,
* but this behavior is configurable via the enableIfMissing property.
* This annotation is repeatable. A bean will only be enabled if all the conditions
* defined by the IfBuildProperty annotations are satisfied.
*/
@Repeatable(IfBuildProperty.List.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
public @interface IfBuildProperty {
/**
* Name of the build time property to check
*/
String name();
/**
* Expected String value of the build time property (specified by name) if the bean is to be enabled
*/
String stringValue();
/**
* Determines if the bean is to be enabled when the property name specified by name has not been specified at all
*/
boolean enableIfMissing() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
@interface List {
IfBuildProperty[] value();
}
}Usage Examples:
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.IfBuildProperty;
// Enabled when feature.analytics property is set to "true"
@ApplicationScoped
@IfBuildProperty(name = "feature.analytics", stringValue = "true")
public class AnalyticsService {
public void trackEvent(String event) {
// Analytics implementation
}
}
// Enabled when property is missing (not defined)
@ApplicationScoped
@IfBuildProperty(name = "feature.experimental", stringValue = "enabled", enableIfMissing = true)
public class ExperimentalFeature {
public void experimentalOperation() {
// Experimental feature enabled by default
}
}
// Multiple conditions - both properties must match
@ApplicationScoped
@IfBuildProperty(name = "database.type", stringValue = "postgresql")
@IfBuildProperty(name = "database.ssl", stringValue = "true")
public class SecurePostgreSQLService {
public void connectToSecureDatabase() {
// PostgreSQL with SSL implementation
}
}Enables beans when build-time properties do NOT match specified values (inverse of IfBuildProperty).
/**
* When applied to a bean class or producer method (or field), the bean will only be enabled
* if the Quarkus build time property does not match the provided value.
* By default, the bean is not enabled when the build time property is not defined at all,
* but this behavior is configurable via the enableIfMissing property.
* This annotation is repeatable. A bean will only be enabled if all the conditions
* defined by the UnlessBuildProperty annotations are satisfied.
*/
@Repeatable(UnlessBuildProperty.List.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
public @interface UnlessBuildProperty {
/**
* Name of the build time property to check
*/
String name();
/**
* The bean is enabled if the build time property (specified by name) does not match this value.
*/
String stringValue();
/**
* Determines if the bean is enabled when the property name specified by name has not been specified at all
*/
boolean enableIfMissing() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
@interface List {
UnlessBuildProperty[] value();
}
}Usage Examples:
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.UnlessBuildProperty;
// Enabled when cache.enabled property is NOT set to "false"
@ApplicationScoped
@UnlessBuildProperty(name = "cache.enabled", stringValue = "false")
public class CacheService {
public void cache(String key, Object value) {
// Caching implementation
}
}
// Enabled when debug.mode property is NOT set to "true"
@ApplicationScoped
@UnlessBuildProperty(name = "debug.mode", stringValue = "true")
public class ProductionOptimizedService {
public void performOptimizedOperation() {
// Production-optimized implementation
}
}
// Enabled when missing property should enable the bean
@ApplicationScoped
@UnlessBuildProperty(name = "feature.disabled", stringValue = "true", enableIfMissing = true)
public class DefaultEnabledFeature {
public void defaultBehavior() {
// Enabled unless explicitly disabled
}
}Both annotations work with producer methods for conditional bean creation.
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.arc.properties.UnlessBuildProperty;
@ApplicationScoped
public class StorageConfigProducer {
@Produces
@IfBuildProperty(name = "storage.type", stringValue = "s3")
public StorageProvider s3StorageProvider() {
return new S3StorageProvider();
}
@Produces
@IfBuildProperty(name = "storage.type", stringValue = "local")
public StorageProvider localStorageProvider() {
return new LocalStorageProvider();
}
@Produces
@UnlessBuildProperty(name = "storage.type", stringValue = "s3")
@UnlessBuildProperty(name = "storage.type", stringValue = "local")
public StorageProvider defaultStorageProvider() {
return new DefaultStorageProvider();
}
}
interface StorageProvider {
void store(String key, byte[] data);
}
class S3StorageProvider implements StorageProvider {
public void store(String key, byte[] data) {
// S3 implementation
}
}
class LocalStorageProvider implements StorageProvider {
public void store(String key, byte[] data) {
// Local file system implementation
}
}
class DefaultStorageProvider implements StorageProvider {
public void store(String key, byte[] data) {
// Default implementation
}
}Combine multiple conditions for sophisticated bean activation rules.
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.arc.properties.UnlessBuildProperty;
// Complex service that requires multiple conditions
@ApplicationScoped
@IfBuildProperty(name = "payment.provider", stringValue = "stripe")
@IfBuildProperty(name = "payment.webhooks", stringValue = "true")
@UnlessBuildProperty(name = "payment.test-mode", stringValue = "true")
public class ProductionStripeWebhookHandler {
public void handleWebhook(String payload) {
// Production Stripe webhook handling
}
}
// Alternative implementation for different conditions
@ApplicationScoped
@IfBuildProperty(name = "payment.provider", stringValue = "stripe")
@IfBuildProperty(name = "payment.test-mode", stringValue = "true")
public class TestStripeWebhookHandler {
public void handleWebhook(String payload) {
// Test mode Stripe webhook handling
}
}Build properties are configured through various sources:
# application.properties
feature.analytics=true
database.type=postgresql
database.ssl=true
cache.enabled=true
storage.type=s3
payment.provider=stripe
payment.webhooks=true
payment.test-mode=false# application-dev.properties
debug.mode=true
feature.experimental=enabled
payment.test-mode=true
# application-prod.properties
debug.mode=false
cache.enabled=true
payment.test-mode=false# System properties
java -Dfeature.analytics=true -jar application.jar
# Environment variables
export FEATURE_ANALYTICS=true
export DATABASE_TYPE=postgresql// Feature flag implementation
@ApplicationScoped
@IfBuildProperty(name = "features.new-ui", stringValue = "enabled")
public class NewUIRenderer implements UIRenderer {
public String render() {
return "New UI implementation";
}
}
@ApplicationScoped
@UnlessBuildProperty(name = "features.new-ui", stringValue = "enabled")
public class LegacyUIRenderer implements UIRenderer {
public String render() {
return "Legacy UI implementation";
}
}// Database-specific implementations
@ApplicationScoped
@IfBuildProperty(name = "quarkus.datasource.db-kind", stringValue = "postgresql")
public class PostgreSQLSpecificService {
public void usePostgreSQLFeatures() {
// PostgreSQL-specific functionality
}
}
@ApplicationScoped
@IfBuildProperty(name = "quarkus.datasource.db-kind", stringValue = "mysql")
public class MySQLSpecificService {
public void useMySQLFeatures() {
// MySQL-specific functionality
}
}// External service integration toggle
@ApplicationScoped
@IfBuildProperty(name = "integrations.slack", stringValue = "true")
public class SlackNotificationService implements NotificationService {
public void notify(String message) {
// Slack integration
}
}
@ApplicationScoped
@IfBuildProperty(name = "integrations.email", stringValue = "true")
public class EmailNotificationService implements NotificationService {
public void notify(String message) {
// Email integration
}
}
@ApplicationScoped
@UnlessBuildProperty(name = "integrations.slack", stringValue = "true")
@UnlessBuildProperty(name = "integrations.email", stringValue = "true")
public class LoggingNotificationService implements NotificationService {
public void notify(String message) {
// Fallback logging implementation
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-quarkus--quarkus-arc