or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbean-container.mdbuild-items.mdconfiguration.mdindex.mdprocessors.md

advanced-features.mddocs/

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.