or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bean-container.mdbean-invocation.mdbuild-profiles.mdbuild-properties.mdindex.mdinterceptor-integration.mdlogger-injection.mdruntime-lookup.md

bean-invocation.mddocs/

0

# Bean Invocation Utilities

1

2

Utility interfaces for invoking bean methods with automatic context management and lookup operations. These utilities provide convenient patterns for method invocation and bean resolution.

3

4

## Capabilities

5

6

### BeanInvoker Interface

7

8

Interface for invoking bean methods with automatic request context management.

9

10

```java { .api }

11

/**

12

* Invokes a business method of a bean. The request context is activated if necessary.

13

*/

14

public interface BeanInvoker<T> {

15

/**

16

* Default implementation that manages request context automatically.

17

* If request context is already active, delegates to invokeBean().

18

* If request context is not active, activates it, calls invokeBean(), then terminates it.

19

*/

20

default void invoke(T param) throws Exception;

21

22

/**

23

* Abstract method that must be implemented to define the actual bean invocation logic.

24

*/

25

void invokeBean(T param) throws Exception;

26

}

27

```

28

29

**Usage Examples:**

30

31

```java

32

import io.quarkus.arc.runtime.BeanInvoker;

33

import io.quarkus.arc.Arc;

34

import jakarta.enterprise.context.ApplicationScoped;

35

36

// Custom invoker for user processing

37

public class UserProcessingInvoker implements BeanInvoker<String> {

38

39

@Override

40

public void invokeBean(String userId) throws Exception {

41

// Get the actual service bean

42

UserService userService = Arc.container().instance(UserService.class).get();

43

44

// Perform the business operation

45

userService.processUser(userId);

46

userService.updateLastProcessed(userId);

47

}

48

}

49

50

// Usage

51

@ApplicationScoped

52

public class UserManager {

53

54

public void processUserWithContextManagement(String userId) {

55

UserProcessingInvoker invoker = new UserProcessingInvoker();

56

57

try {

58

// Context is automatically managed

59

invoker.invoke(userId);

60

} catch (Exception e) {

61

System.err.println("Failed to process user: " + userId);

62

throw new RuntimeException(e);

63

}

64

}

65

}

66

67

// Complex invoker with multiple operations

68

public class OrderProcessingInvoker implements BeanInvoker<OrderRequest> {

69

70

@Override

71

public void invokeBean(OrderRequest request) throws Exception {

72

// All these operations will run within the same request context

73

OrderService orderService = Arc.container().instance(OrderService.class).get();

74

PaymentService paymentService = Arc.container().instance(PaymentService.class).get();

75

InventoryService inventoryService = Arc.container().instance(InventoryService.class).get();

76

77

// Process order

78

Order order = orderService.createOrder(request);

79

80

// Process payment

81

PaymentResult payment = paymentService.processPayment(request.getPaymentInfo());

82

83

// Update inventory

84

inventoryService.reserveItems(request.getItems());

85

86

// Finalize order

87

orderService.finalizeOrder(order, payment);

88

}

89

}

90

91

// Supporting classes

92

class OrderRequest {

93

private PaymentInfo paymentInfo;

94

private List<OrderItem> items;

95

96

public PaymentInfo getPaymentInfo() { return paymentInfo; }

97

public List<OrderItem> getItems() { return items; }

98

}

99

100

class Order { }

101

class PaymentInfo { }

102

class PaymentResult { }

103

class OrderItem { }

104

105

interface UserService {

106

void processUser(String userId);

107

void updateLastProcessed(String userId);

108

}

109

110

interface OrderService {

111

Order createOrder(OrderRequest request);

112

void finalizeOrder(Order order, PaymentResult payment);

113

}

114

115

interface PaymentService {

116

PaymentResult processPayment(PaymentInfo paymentInfo);

117

}

118

119

interface InventoryService {

120

void reserveItems(List<OrderItem> items);

121

}

122

```

123

124

### BeanLookupSupplier Class

125

126

Supplier implementation that performs CDI bean lookup, bridging supplier pattern with CDI.

127

128

```java { .api }

129

/**

130

* Supplier that performs CDI bean lookup using Arc container.

131

*/

132

public class BeanLookupSupplier implements Supplier<Object> {

133

private Class<?> type;

134

135

public BeanLookupSupplier();

136

public BeanLookupSupplier(Class<?> type);

137

138

public Class<?> getType();

139

public BeanLookupSupplier setType(Class<?> type);

140

141

/**

142

* Performs bean lookup using Arc.container().instance(type).get()

143

*/

144

public Object get();

145

}

146

```

147

148

**Usage Examples:**

149

150

```java

151

import io.quarkus.arc.runtime.BeanLookupSupplier;

152

import jakarta.enterprise.context.ApplicationScoped;

153

import java.util.function.Supplier;

154

import java.util.concurrent.CompletableFuture;

155

156

@ApplicationScoped

157

public class SupplierBasedService {

158

159

public void demonstrateBasicUsage() {

160

// Create supplier for specific bean type

161

Supplier<Object> userServiceSupplier = new BeanLookupSupplier(UserService.class);

162

163

// Use the supplier

164

UserService userService = (UserService) userServiceSupplier.get();

165

userService.processUser("user123");

166

}

167

168

public void demonstrateFluentUsage() {

169

// Fluent API usage

170

BeanLookupSupplier supplier = new BeanLookupSupplier()

171

.setType(NotificationService.class);

172

173

NotificationService notificationService = (NotificationService) supplier.get();

174

notificationService.sendNotification("Hello World");

175

}

176

177

public void demonstrateAsyncUsage() {

178

// Use supplier in async contexts

179

Supplier<Object> emailServiceSupplier = new BeanLookupSupplier(EmailService.class);

180

181

CompletableFuture.supplyAsync(() -> {

182

EmailService emailService = (EmailService) emailServiceSupplier.get();

183

return emailService.sendEmail("test@example.com", "Subject", "Body");

184

}).thenAccept(result -> {

185

System.out.println("Email sent: " + result);

186

});

187

}

188

189

public <T> void demonstrateGenericWrapper(Class<T> beanType) {

190

// Generic wrapper for type safety

191

TypedBeanSupplier<T> typedSupplier = new TypedBeanSupplier<>(beanType);

192

T service = typedSupplier.get();

193

194

// Now we have type-safe access

195

if (service instanceof Processable) {

196

((Processable) service).process("data");

197

}

198

}

199

}

200

201

// Type-safe wrapper around BeanLookupSupplier

202

class TypedBeanSupplier<T> implements Supplier<T> {

203

private final BeanLookupSupplier delegate;

204

private final Class<T> type;

205

206

public TypedBeanSupplier(Class<T> type) {

207

this.type = type;

208

this.delegate = new BeanLookupSupplier(type);

209

}

210

211

@Override

212

@SuppressWarnings("unchecked")

213

public T get() {

214

return (T) delegate.get();

215

}

216

217

public Class<T> getType() {

218

return type;

219

}

220

}

221

222

// Supporting interfaces

223

interface NotificationService {

224

void sendNotification(String message);

225

}

226

227

interface EmailService {

228

boolean sendEmail(String to, String subject, String body);

229

}

230

```

231

232

### Advanced Invocation Patterns

233

234

Complex patterns combining both utilities for sophisticated invocation scenarios.

235

236

```java

237

import io.quarkus.arc.runtime.BeanInvoker;

238

import io.quarkus.arc.runtime.BeanLookupSupplier;

239

import jakarta.enterprise.context.ApplicationScoped;

240

import java.util.concurrent.CompletableFuture;

241

import java.util.function.Supplier;

242

243

@ApplicationScoped

244

public class AdvancedInvocationService {

245

246

// Batch processing with context management

247

public void batchProcessWithInvoker(List<String> userIds) {

248

BeanInvoker<List<String>> batchInvoker = new BeanInvoker<List<String>>() {

249

@Override

250

public void invokeBean(List<String> ids) throws Exception {

251

UserService userService = (UserService) new BeanLookupSupplier(UserService.class).get();

252

253

for (String id : ids) {

254

userService.processUser(id);

255

}

256

257

// Perform batch cleanup

258

userService.flushBatchProcessing();

259

}

260

};

261

262

try {

263

batchInvoker.invoke(userIds);

264

} catch (Exception e) {

265

throw new RuntimeException("Batch processing failed", e);

266

}

267

}

268

269

// Async processing with suppliers

270

public CompletableFuture<String> asyncProcessWithSupplier(String data) {

271

Supplier<Object> dataProcessorSupplier = new BeanLookupSupplier(DataProcessor.class);

272

273

return CompletableFuture.supplyAsync(() -> {

274

DataProcessor processor = (DataProcessor) dataProcessorSupplier.get();

275

return processor.processData(data);

276

});

277

}

278

279

// Conditional invocation based on bean availability

280

public void conditionalInvocation(String message) {

281

BeanInvoker<String> conditionalInvoker = new BeanInvoker<String>() {

282

@Override

283

public void invokeBean(String msg) throws Exception {

284

// Try to get optional service

285

BeanLookupSupplier auditSupplier = new BeanLookupSupplier()

286

.setType(AuditService.class);

287

288

try {

289

AuditService auditService = (AuditService) auditSupplier.get();

290

auditService.audit(msg);

291

} catch (Exception e) {

292

// Audit service not available, log instead

293

System.out.println("Audit not available, logging: " + msg);

294

}

295

296

// Always perform main operation

297

MainService mainService = (MainService) new BeanLookupSupplier(MainService.class).get();

298

mainService.process(msg);

299

}

300

};

301

302

try {

303

conditionalInvoker.invoke(message);

304

} catch (Exception e) {

305

throw new RuntimeException("Conditional invocation failed", e);

306

}

307

}

308

309

// Chain multiple operations with context preservation

310

public void chainedOperations(ProcessingRequest request) {

311

BeanInvoker<ProcessingRequest> chainedInvoker = new BeanInvoker<ProcessingRequest>() {

312

@Override

313

public void invokeBean(ProcessingRequest req) throws Exception {

314

// Create suppliers for all needed services

315

Supplier<Object> validatorSupplier = new BeanLookupSupplier(ValidationService.class);

316

Supplier<Object> transformerSupplier = new BeanLookupSupplier(TransformationService.class);

317

Supplier<Object> persisterSupplier = new BeanLookupSupplier(PersistenceService.class);

318

319

// Execute chain within single request context

320

ValidationService validator = (ValidationService) validatorSupplier.get();

321

validator.validate(req);

322

323

TransformationService transformer = (TransformationService) transformerSupplier.get();

324

ProcessedData processed = transformer.transform(req);

325

326

PersistenceService persister = (PersistenceService) persisterSupplier.get();

327

persister.persist(processed);

328

}

329

};

330

331

try {

332

chainedInvoker.invoke(request);

333

} catch (Exception e) {

334

throw new RuntimeException("Chained operations failed", e);

335

}

336

}

337

338

// Factory pattern using suppliers

339

public <T> ServiceFactory<T> createServiceFactory(Class<T> serviceType) {

340

return new ServiceFactory<T>() {

341

private final Supplier<Object> supplier = new BeanLookupSupplier(serviceType);

342

343

@Override

344

@SuppressWarnings("unchecked")

345

public T createService() {

346

return (T) supplier.get();

347

}

348

349

@Override

350

public void withService(ServiceConsumer<T> consumer) {

351

T service = createService();

352

consumer.accept(service);

353

}

354

};

355

}

356

357

public void demonstrateServiceFactory() {

358

ServiceFactory<ReportService> reportFactory = createServiceFactory(ReportService.class);

359

360

// Use factory to create and use service

361

reportFactory.withService(reportService -> {

362

reportService.generateReport("monthly");

363

reportService.sendReport();

364

});

365

}

366

}

367

368

// Supporting interfaces and classes

369

interface DataProcessor {

370

String processData(String data);

371

}

372

373

interface AuditService {

374

void audit(String message);

375

}

376

377

interface MainService {

378

void process(String message);

379

}

380

381

interface ValidationService {

382

void validate(ProcessingRequest request);

383

}

384

385

interface TransformationService {

386

ProcessedData transform(ProcessingRequest request);

387

}

388

389

interface PersistenceService {

390

void persist(ProcessedData data);

391

}

392

393

interface ReportService {

394

void generateReport(String type);

395

void sendReport();

396

}

397

398

interface ServiceFactory<T> {

399

T createService();

400

void withService(ServiceConsumer<T> consumer);

401

}

402

403

@FunctionalInterface

404

interface ServiceConsumer<T> {

405

void accept(T service);

406

}

407

408

class ProcessingRequest { }

409

class ProcessedData { }

410

411

// Extended UserService interface

412

interface UserService {

413

void processUser(String userId);

414

void updateLastProcessed(String userId);

415

void flushBatchProcessing();

416

}

417

```

418

419

### Integration with Async Processing

420

421

Examples of using bean invocation utilities in asynchronous contexts.

422

423

```java

424

import io.quarkus.arc.runtime.BeanInvoker;

425

import io.quarkus.arc.runtime.BeanLookupSupplier;

426

import jakarta.enterprise.context.ApplicationScoped;

427

import java.util.concurrent.*;

428

import java.util.function.Supplier;

429

430

@ApplicationScoped

431

public class AsyncInvocationService {

432

433

private final ExecutorService executor = Executors.newFixedThreadPool(5);

434

435

public CompletableFuture<Void> asyncInvokeWithContext(String data) {

436

BeanInvoker<String> asyncInvoker = new BeanInvoker<String>() {

437

@Override

438

public void invokeBean(String input) throws Exception {

439

AsyncProcessingService service = (AsyncProcessingService)

440

new BeanLookupSupplier(AsyncProcessingService.class).get();

441

service.processAsync(input);

442

}

443

};

444

445

return CompletableFuture.runAsync(() -> {

446

try {

447

asyncInvoker.invoke(data);

448

} catch (Exception e) {

449

throw new RuntimeException(e);

450

}

451

}, executor);

452

}

453

454

public CompletableFuture<String> asyncSupplyWithBean(String input) {

455

Supplier<Object> serviceSupplier = new BeanLookupSupplier(ComputationService.class);

456

457

return CompletableFuture.supplyAsync(() -> {

458

ComputationService service = (ComputationService) serviceSupplier.get();

459

return service.compute(input);

460

}, executor);

461

}

462

463

public void parallelProcessing(List<String> items) {

464

List<CompletableFuture<Void>> futures = items.stream()

465

.map(item -> {

466

BeanInvoker<String> itemInvoker = new BeanInvoker<String>() {

467

@Override

468

public void invokeBean(String data) throws Exception {

469

ItemProcessor processor = (ItemProcessor)

470

new BeanLookupSupplier(ItemProcessor.class).get();

471

processor.processItem(data);

472

}

473

};

474

475

return CompletableFuture.runAsync(() -> {

476

try {

477

itemInvoker.invoke(item);

478

} catch (Exception e) {

479

throw new RuntimeException(e);

480

}

481

}, executor);

482

})

483

.collect(Collectors.toList());

484

485

// Wait for all to complete

486

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

487

}

488

489

// Cleanup

490

@PreDestroy

491

public void shutdown() {

492

executor.shutdown();

493

}

494

}

495

496

// Supporting interfaces

497

interface AsyncProcessingService {

498

void processAsync(String data);

499

}

500

501

interface ComputationService {

502

String compute(String input);

503

}

504

505

interface ItemProcessor {

506

void processItem(String item);

507

}

508

```

509

510

## Best Practices

511

512

### Error Handling

513

514

```java

515

public class SafeInvocationPractices {

516

517

public void safeInvokerUsage() {

518

BeanInvoker<String> safeInvoker = new BeanInvoker<String>() {

519

@Override

520

public void invokeBean(String data) throws Exception {

521

try {

522

RiskyService service = (RiskyService)

523

new BeanLookupSupplier(RiskyService.class).get();

524

service.riskyOperation(data);

525

} catch (ServiceException e) {

526

// Handle service-specific exceptions

527

System.err.println("Service error: " + e.getMessage());

528

throw e;

529

} catch (Exception e) {

530

// Handle unexpected exceptions

531

System.err.println("Unexpected error: " + e.getMessage());

532

throw new RuntimeException("Operation failed", e);

533

}

534

}

535

};

536

537

try {

538

safeInvoker.invoke("test-data");

539

} catch (Exception e) {

540

// Final error handling

541

System.err.println("Invocation failed: " + e.getMessage());

542

}

543

}

544

545

public void safeSupplierUsage() {

546

BeanLookupSupplier supplier = new BeanLookupSupplier()

547

.setType(OptionalService.class);

548

549

try {

550

OptionalService service = (OptionalService) supplier.get();

551

service.performOperation();

552

} catch (Exception e) {

553

// Handle bean lookup failures

554

System.err.println("Service not available: " + e.getMessage());

555

// Provide fallback behavior

556

performFallbackOperation();

557

}

558

}

559

560

private void performFallbackOperation() {

561

System.out.println("Executing fallback operation");

562

}

563

}

564

565

interface RiskyService {

566

void riskyOperation(String data) throws ServiceException;

567

}

568

569

interface OptionalService {

570

void performOperation();

571

}

572

573

class ServiceException extends Exception {

574

public ServiceException(String message) {

575

super(message);

576

}

577

}

578

```

579

580

### Resource Management

581

582

```java

583

public class ResourceManagementPractices {

584

585

public void properResourceHandling() {

586

// Use try-with-resources pattern when applicable

587

BeanInvoker<String> resourceInvoker = new BeanInvoker<String>() {

588

@Override

589

public void invokeBean(String data) throws Exception {

590

ResourceIntensiveService service = (ResourceIntensiveService)

591

new BeanLookupSupplier(ResourceIntensiveService.class).get();

592

593

// Service should implement AutoCloseable if it manages resources

594

if (service instanceof AutoCloseable) {

595

try (AutoCloseable closeable = (AutoCloseable) service) {

596

service.processWithResources(data);

597

}

598

} else {

599

service.processWithResources(data);

600

}

601

}

602

};

603

604

try {

605

resourceInvoker.invoke("resource-intensive-data");

606

} catch (Exception e) {

607

throw new RuntimeException("Resource handling failed", e);

608

}

609

}

610

}

611

612

interface ResourceIntensiveService {

613

void processWithResources(String data);

614

}

615

```