0
# Advanced Features
1
2
Advanced CDI features provide sophisticated capabilities for interceptors, decorators, observers, custom scopes, and build-time transformations. These features enable deep customization of CDI behavior and advanced architectural patterns.
3
4
## Capabilities
5
6
### Annotation Transformation
7
8
Transform annotations on CDI components at build time for dynamic behavior modification.
9
10
```java { .api }
11
/**
12
* Transform annotations on CDI components
13
*/
14
public class AnnotationsTransformerBuildItem extends MultiBuildItem {
15
public AnnotationsTransformerBuildItem(AnnotationTransformation transformation);
16
17
/**
18
* Get the annotation transformation
19
*/
20
public AnnotationTransformation getAnnotationTransformation();
21
}
22
23
/**
24
* Annotation transformation interface
25
*/
26
public interface AnnotationTransformation {
27
/**
28
* Check if this transformation applies to the given class
29
*/
30
boolean appliesTo(org.jboss.jandex.ClassInfo clazz);
31
32
/**
33
* Transform annotations on the class
34
*/
35
void transform(TransformationContext context);
36
}
37
38
/**
39
* Context for annotation transformations
40
*/
41
public interface TransformationContext {
42
/**
43
* Get the target class being transformed
44
*/
45
ClassInfo getTarget();
46
47
/**
48
* Transform annotations by adding, removing, or modifying them
49
*/
50
Transformation transform();
51
}
52
```
53
54
**Usage Examples:**
55
56
```java
57
// Transform service classes to add scopes automatically
58
@BuildStep
59
AnnotationsTransformerBuildItem autoScopeServices() {
60
return new AnnotationsTransformerBuildItem(new AnnotationTransformation() {
61
@Override
62
public boolean appliesTo(ClassInfo clazz) {
63
return clazz.name().toString().endsWith("Service") &&
64
!clazz.classAnnotation(DotNames.APPLICATION_SCOPED);
65
}
66
67
@Override
68
public void transform(TransformationContext context) {
69
context.transform()
70
.add(ApplicationScoped.class)
71
.done();
72
}
73
});
74
}
75
76
// Add qualifiers based on class packages
77
@BuildStep
78
AnnotationsTransformerBuildItem addPackageQualifiers() {
79
return new AnnotationsTransformerBuildItem(AnnotationTransformation.forClasses()
80
.whenContains("com.example.core")
81
.thenTransform(context ->
82
context.transform().add(createQualifier("Core")).done()));
83
}
84
```
85
86
### Injection Point Transformation
87
88
Modify injection points at build time to customize dependency injection behavior.
89
90
```java { .api }
91
/**
92
* Transform injection points at build time
93
*/
94
public class InjectionPointTransformerBuildItem extends MultiBuildItem {
95
public InjectionPointTransformerBuildItem(InjectionPointsTransformer transformer);
96
97
/**
98
* Get the injection point transformer
99
*/
100
public InjectionPointsTransformer getInjectionPointsTransformer();
101
}
102
103
/**
104
* Injection point transformer interface
105
*/
106
public interface InjectionPointsTransformer {
107
/**
108
* Check if this transformer applies to the given injection point
109
*/
110
boolean appliesTo(Type requiredType, Set<AnnotationInstance> qualifiers);
111
112
/**
113
* Transform the injection point
114
*/
115
void transform(TransformationContext context);
116
}
117
```
118
119
**Usage Examples:**
120
121
```java
122
// Transform injection points to add automatic qualifiers
123
@BuildStep
124
InjectionPointTransformerBuildItem autoQualifyInjection() {
125
return new InjectionPointTransformerBuildItem((requiredType, qualifiers, context) -> {
126
if (requiredType.name().toString().startsWith("com.example.database")) {
127
context.transform().add(createAnnotation("Database")).done();
128
}
129
});
130
}
131
```
132
133
### Observer Method Processing
134
135
Handle CDI observer methods and events with build-time processing and validation.
136
137
```java { .api }
138
/**
139
* Transform observer methods at build time
140
*/
141
public class ObserverTransformerBuildItem extends MultiBuildItem {
142
public ObserverTransformerBuildItem(ObserverTransformer transformer);
143
144
/**
145
* Get the observer transformer instance
146
*/
147
public ObserverTransformer getInstance();
148
}
149
150
/**
151
* Observer transformer interface
152
*/
153
public interface ObserverTransformer {
154
/**
155
* Check if this transformer applies to the observer method
156
*/
157
boolean appliesTo(MethodInfo observerMethod, AnnotationInstance observes);
158
159
/**
160
* Transform the observer method
161
*/
162
void transform(ObserverTransformationContext context);
163
}
164
165
/**
166
* Marker for observer registration phase completion
167
*/
168
public class ObserverRegistrationPhaseBuildItem extends SimpleBuildItem {
169
public ObserverRegistrationPhaseBuildItem(BeanProcessor.Builder builder);
170
public BeanProcessor.Builder getBeanProcessor();
171
}
172
```
173
174
**Usage Examples:**
175
176
```java
177
// Transform observers to add transaction support
178
@BuildStep
179
ObserverTransformerBuildItem addTransactionalObservers() {
180
return new ObserverTransformerBuildItem((method, observes, context) -> {
181
if (method.declaringClass().name().toString().contains("transactional")) {
182
context.transform().add(Transactional.class).done();
183
}
184
});
185
}
186
```
187
188
### Interceptor and Decorator Support
189
190
Register and configure interceptors and decorators with build-time binding resolution.
191
192
```java { .api }
193
/**
194
* Register custom interceptor binding registrars
195
*/
196
public class InterceptorBindingRegistrarBuildItem extends MultiBuildItem {
197
public InterceptorBindingRegistrarBuildItem(InterceptorBindingRegistrar registrar);
198
public InterceptorBindingRegistrar getInterceptorBindingRegistrar();
199
}
200
201
/**
202
* Interceptor binding registrar interface
203
*/
204
public interface InterceptorBindingRegistrar {
205
/**
206
* Register custom interceptor bindings
207
*/
208
void register(RegistrationContext registrationContext);
209
}
210
211
/**
212
* Interceptor resolver for build-time resolution
213
*/
214
public class InterceptorResolverBuildItem extends SimpleBuildItem {
215
public InterceptorResolverBuildItem(InterceptorResolver resolver);
216
public InterceptorResolver getInterceptorResolver();
217
}
218
219
/**
220
* Interceptor resolver interface
221
*/
222
public interface InterceptorResolver {
223
/**
224
* Resolve interceptors for a given bean
225
*/
226
List<InterceptorInfo> resolve(BeanInfo bean);
227
228
/**
229
* Resolve interceptors for a method
230
*/
231
List<InterceptorInfo> resolve(MethodInfo method, BeanInfo bean);
232
}
233
```
234
235
**Usage Examples:**
236
237
```java
238
// Register custom interceptor bindings
239
@BuildStep
240
InterceptorBindingRegistrarBuildItem registerCustomInterceptors() {
241
return new InterceptorBindingRegistrarBuildItem(context -> {
242
context.register(DotName.createSimple("com.example.Audit"),
243
Collections.emptySet());
244
context.register(DotName.createSimple("com.example.Cache"),
245
Collections.emptySet());
246
});
247
}
248
249
// Provide custom interceptor resolver
250
@BuildStep
251
InterceptorResolverBuildItem customInterceptorResolver() {
252
return new InterceptorResolverBuildItem(new InterceptorResolver() {
253
@Override
254
public List<InterceptorInfo> resolve(BeanInfo bean) {
255
// Custom interceptor resolution logic
256
return resolveCustomInterceptors(bean);
257
}
258
});
259
}
260
```
261
262
### Custom Scope Management
263
264
Register and manage custom CDI scopes with build-time configuration.
265
266
```java { .api }
267
/**
268
* Register custom CDI scope annotations
269
*/
270
public class CustomScopeBuildItem extends MultiBuildItem {
271
public CustomScopeBuildItem(Class<? extends Annotation> scope);
272
public CustomScopeBuildItem(DotName annotationName);
273
274
/**
275
* Get the scope annotation name
276
*/
277
public DotName getAnnotationName();
278
}
279
280
/**
281
* Custom scope annotations collection
282
*/
283
public class CustomScopeAnnotationsBuildItem extends SimpleBuildItem {
284
public CustomScopeAnnotationsBuildItem(Set<DotName> scopes);
285
286
/**
287
* Get all registered custom scope annotations
288
*/
289
public Set<DotName> getScopes();
290
}
291
292
/**
293
* Automatically add scope annotations to classes
294
*/
295
public class AutoAddScopeBuildItem extends MultiBuildItem {
296
public static Builder builder();
297
298
public boolean isContainerServicesRequired();
299
public DotName getDefaultScope();
300
public boolean isUnremovable();
301
public String getReason();
302
public int getPriority();
303
public BiConsumer<DotName, String> getScopeAlreadyAdded();
304
305
/**
306
* Test if this auto-scope rule applies to the given class
307
*/
308
public boolean test(ClassInfo clazz, Collection<AnnotationInstance> annotations, IndexView index);
309
}
310
311
/**
312
* Builder for auto-scope rules
313
*/
314
public static class AutoAddScopeBuildItem.Builder {
315
public Builder containsOne(String... values);
316
public Builder containsAll(String... values);
317
public Builder anyOf(MatchPredicate... predicates);
318
public Builder defaultScope(DotName scope);
319
public Builder unremovable();
320
public Builder reason(String reason);
321
public Builder priority(int priority);
322
public Builder scopeAlreadyAdded(BiConsumer<DotName, String> consumer);
323
public AutoAddScopeBuildItem build();
324
}
325
```
326
327
**Usage Examples:**
328
329
```java
330
// Register custom scope
331
@BuildStep
332
CustomScopeBuildItem registerTenantScope() {
333
return new CustomScopeBuildItem(TenantScoped.class);
334
}
335
336
// Auto-add scopes based on naming conventions
337
@BuildStep
338
AutoAddScopeBuildItem autoScopeByName() {
339
return AutoAddScopeBuildItem.builder()
340
.containsOne("Repository", "Service", "Controller")
341
.defaultScope(DotNames.APPLICATION_SCOPED)
342
.reason("Auto-scope for service layer classes")
343
.priority(100)
344
.build();
345
}
346
347
// Provide all custom scopes
348
@BuildStep
349
CustomScopeAnnotationsBuildItem allCustomScopes() {
350
return new CustomScopeAnnotationsBuildItem(Set.of(
351
DotName.createSimple("com.example.TenantScoped"),
352
DotName.createSimple("com.example.RequestScoped"),
353
DotName.createSimple("com.example.SessionScoped")
354
));
355
}
356
```
357
358
### Qualifier Registration
359
360
Register custom CDI qualifiers for dependency injection disambiguation.
361
362
```java { .api }
363
/**
364
* Register custom qualifier registrars
365
*/
366
public class QualifierRegistrarBuildItem extends MultiBuildItem {
367
public QualifierRegistrarBuildItem(QualifierRegistrar registrar);
368
public QualifierRegistrar getQualifierRegistrar();
369
}
370
371
/**
372
* Qualifier registrar interface
373
*/
374
public interface QualifierRegistrar {
375
/**
376
* Register custom qualifiers
377
*/
378
void register(RegistrationContext context);
379
}
380
```
381
382
**Usage Examples:**
383
384
```java
385
// Register custom qualifiers
386
@BuildStep
387
QualifierRegistrarBuildItem registerCustomQualifiers() {
388
return new QualifierRegistrarBuildItem(context -> {
389
context.register(DotName.createSimple("com.example.Database"));
390
context.register(DotName.createSimple("com.example.Cache"));
391
});
392
}
393
```
394
395
### Stereotype Support
396
397
Register and manage CDI stereotypes for grouping common annotations.
398
399
```java { .api }
400
/**
401
* Register stereotype registrars
402
*/
403
public class StereotypeRegistrarBuildItem extends MultiBuildItem {
404
public StereotypeRegistrarBuildItem(StereotypeRegistrar registrar);
405
public StereotypeRegistrar getStereotypeRegistrar();
406
}
407
408
/**
409
* Stereotype registrar interface
410
*/
411
public interface StereotypeRegistrar {
412
/**
413
* Register custom stereotypes
414
*/
415
void register(RegistrationContext context);
416
}
417
```
418
419
### Build-Time Conditions
420
421
Support for conditional CDI components based on build-time conditions.
422
423
```java { .api }
424
/**
425
* Build-time condition for conditional CDI components
426
*/
427
public class BuildTimeConditionBuildItem extends MultiBuildItem {
428
public BuildTimeConditionBuildItem(String condition, boolean enabled);
429
430
public String getCondition();
431
public boolean isEnabled();
432
}
433
```
434
435
**Usage Examples:**
436
437
```java
438
// Register build-time conditions
439
@BuildStep
440
BuildTimeConditionBuildItem databaseCondition(DatabaseConfig config) {
441
return new BuildTimeConditionBuildItem(
442
"database.enabled",
443
config.enabled()
444
);
445
}
446
```
447
448
### Resource Injection
449
450
Support for @Resource annotation and custom resource injection patterns.
451
452
```java { .api }
453
/**
454
* Register resource injection annotations
455
*/
456
public class ResourceAnnotationBuildItem extends MultiBuildItem {
457
public ResourceAnnotationBuildItem(DotName annotationName);
458
public DotName getAnnotationName();
459
}
460
```
461
462
### Static Method Interception
463
464
Support for intercepting static methods at build time.
465
466
```java { .api }
467
/**
468
* Register intercepted static methods
469
*/
470
public class InterceptedStaticMethodBuildItem extends MultiBuildItem {
471
public InterceptedStaticMethodBuildItem(String className, String methodName,
472
String descriptor, boolean needsCallerInstance);
473
474
public String getClassName();
475
public String getMethodName();
476
public String getDescriptor();
477
public boolean needsCallerInstance();
478
}
479
```
480
481
These advanced features provide the foundation for sophisticated CDI customizations, architectural patterns, and framework integrations in Quarkus applications.