or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-config.mdaot-support.mdbean-definition.mdbean-factory.mdindex.mdproperty-access.mdxml-config.md

aot-support.mddocs/

0

# AOT and Native Compilation

1

2

Ahead-of-time compilation support for native image generation, providing build-time optimization and reflection-free bean instantiation. This system enables Spring applications to be compiled to native images with GraalVM, significantly reducing startup time and memory footprint.

3

4

## Capabilities

5

6

### Bean Registration AOT Processing

7

8

Infrastructure for processing bean definitions at build time to generate optimized instantiation code.

9

10

```java { .api }

11

/**

12

* AOT processor that contributes to bean registration code generation.

13

*/

14

interface BeanRegistrationAotProcessor {

15

/**

16

* Process the given RegisteredBean instance ahead of time and return a contribution or null.

17

* @param registeredBean the registered bean to process

18

* @return a BeanRegistrationAotContribution instance or null

19

*/

20

BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean);

21

}

22

23

/**

24

* AOT contribution from a BeanRegistrationAotProcessor, used to register a single bean definition.

25

*/

26

interface BeanRegistrationAotContribution {

27

/**

28

* Apply this contribution to the given BeanRegistrationCode.

29

* @param generationContext the generation context

30

* @param beanRegistrationCode the bean registration code

31

*/

32

void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode);

33

}

34

35

/**

36

* Interface that defines the contract for code that registers a single bean.

37

*/

38

interface BeanRegistrationCode {

39

/**

40

* Return the class name of the bean registration.

41

* @return the class name

42

*/

43

ClassName getClassName();

44

45

/**

46

* Return the methods that contain the bean registration code.

47

* @return the registration methods

48

*/

49

MethodReference[] getMethods();

50

51

/**

52

* Return the instance supplier code generator.

53

* @return the instance supplier code generator

54

*/

55

CodeGenerator getInstanceSupplierCodeGenerator();

56

}

57

58

/**

59

* Interface that defines the contract for code that registers all beans.

60

*/

61

interface BeanRegistrationsCode {

62

/**

63

* Return the class name that contains the bean registrations.

64

* @return the class name

65

*/

66

ClassName getClassName();

67

68

/**

69

* Return the method that contains the bean registration code.

70

* @return the registration method

71

*/

72

MethodReference getInitializerMethod();

73

}

74

```

75

76

### Bean Factory Initialization AOT Processing

77

78

Support for processing bean factory initialization logic at build time.

79

80

```java { .api }

81

/**

82

* AOT processor that contributes to bean factory initialization code generation.

83

*/

84

interface BeanFactoryInitializationAotProcessor {

85

/**

86

* Process the given ConfigurableListableBeanFactory instance ahead of time and return a contribution or null.

87

* @param beanFactory the bean factory to process

88

* @return a BeanFactoryInitializationAotContribution instance or null

89

*/

90

BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory);

91

}

92

93

/**

94

* AOT contribution from a BeanFactoryInitializationAotProcessor, used to initialize a bean factory.

95

*/

96

interface BeanFactoryInitializationAotContribution {

97

/**

98

* Apply this contribution to the given BeanFactoryInitializationCode.

99

* @param generationContext the generation context

100

* @param beanFactoryInitializationCode the bean factory initialization code

101

*/

102

void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode);

103

}

104

105

/**

106

* Interface that defines the contract for code that initializes a bean factory.

107

*/

108

interface BeanFactoryInitializationCode {

109

/**

110

* Return the type of the bean factory.

111

* @return the bean factory type

112

*/

113

TypeSpec.Builder getTypeBuilder();

114

115

/**

116

* Return the methods that contain the bean factory initialization code.

117

* @return the initialization methods

118

*/

119

MethodSpec.Builder[] getMethods();

120

}

121

```

122

123

### Instance Supplier Code Generation

124

125

Code generation for creating optimized instance suppliers that avoid reflection.

126

127

```java { .api }

128

/**

129

* Code generator for instance supplier lambda expressions.

130

*/

131

class InstanceSupplierCodeGenerator {

132

/**

133

* Create a new InstanceSupplierCodeGenerator instance.

134

* @param generationContext the generation context to use

135

* @param className the class name being generated

136

* @param methods the methods that are available

137

* @param allowDirectSupplierShortcut whether to allow direct supplier shortcuts

138

*/

139

public InstanceSupplierCodeGenerator(GenerationContext generationContext, ClassName className,

140

MultiStatement methods, boolean allowDirectSupplierShortcut);

141

142

/**

143

* Generate the instance supplier code for the given registered bean and executable.

144

* @param registeredBean the registered bean

145

* @param constructorOrFactoryMethod the constructor or factory method

146

* @return the generated code block

147

*/

148

public CodeBlock generateCode(RegisteredBean registeredBean, Executable constructorOrFactoryMethod);

149

150

/**

151

* Generate the instance supplier code for the given registered bean and instantiation descriptor.

152

* @param registeredBean the registered bean

153

* @param instantiationDescriptor the instantiation descriptor

154

* @return the generated code block

155

*/

156

public CodeBlock generateCode(RegisteredBean registeredBean, InstantiationDescriptor instantiationDescriptor);

157

158

/**

159

* Generate the instance supplier code for the given registered bean and instance supplier.

160

* @param registeredBean the registered bean

161

* @param instanceSupplier the instance supplier

162

* @return the generated code block

163

*/

164

public CodeBlock generateCode(RegisteredBean registeredBean, InstanceSupplier<?> instanceSupplier);

165

166

/**

167

* Check whether the given bean class has a constructor with an optional parameter.

168

* @param beanClass the bean class to check

169

* @return true if the bean class has a constructor with an optional parameter

170

*/

171

public static boolean hasConstructorWithOptionalParameter(Class<?> beanClass);

172

173

/**

174

* Register reflection hints for the given executable.

175

* @param runtimeHints the runtime hints

176

* @param executable the executable to register hints for

177

*/

178

public void registerRuntimeHints(RuntimeHints runtimeHints, Executable executable);

179

}

180

```

181

182

### Autowired Arguments Code Generation

183

184

Support for generating code that resolves autowired constructor and method arguments.

185

186

```java { .api }

187

/**

188

* Interface for resolving autowired arguments in generated code.

189

*/

190

interface AutowiredArguments {

191

/**

192

* Resolve the arguments for the given parameter types.

193

* @param parameterTypes the parameter types

194

* @return the resolved arguments

195

*/

196

Object[] resolve(Class<?>[] parameterTypes);

197

198

/**

199

* Resolve arguments for the given parameter types starting from the specified index.

200

* @param parameterTypes the parameter types

201

* @param startIndex the start index

202

* @return the resolved arguments

203

*/

204

Object[] resolve(Class<?>[] parameterTypes, int startIndex);

205

}

206

207

/**

208

* Code generator for autowired arguments resolution.

209

*/

210

class AutowiredArgumentsCodeGenerator {

211

/**

212

* Create a new AutowiredArgumentsCodeGenerator.

213

* @param className the class name being generated

214

* @param methods the methods that are available

215

*/

216

public AutowiredArgumentsCodeGenerator(ClassName className, MultiStatement methods);

217

218

/**

219

* Generate code to resolve arguments for the given parameter types.

220

* @param parameterTypes the parameter types

221

* @return the generated code block

222

*/

223

public CodeBlock generateCode(Class<?>[] parameterTypes);

224

225

/**

226

* Generate code to resolve arguments for the given parameter types starting from the specified index.

227

* @param parameterTypes the parameter types

228

* @param startIndex the start index

229

* @return the generated code block

230

*/

231

public CodeBlock generateCode(Class<?>[] parameterTypes, int startIndex);

232

233

/**

234

* Generate code to resolve arguments for the given parameter types with a custom variable name.

235

* @param parameterTypes the parameter types

236

* @param startIndex the start index

237

* @param variableName the variable name to use

238

* @return the generated code block

239

*/

240

public CodeBlock generateCode(Class<?>[] parameterTypes, int startIndex, String variableName);

241

}

242

```

243

244

### Bean Registration Code Fragments

245

246

Customizable code fragments for bean registration generation.

247

248

```java { .api }

249

/**

250

* Interface that defines the various code fragments that are used during bean registration code generation.

251

*/

252

interface BeanRegistrationCodeFragments {

253

/**

254

* Return the target class name for the given registered bean.

255

* @param registeredBean the registered bean

256

* @return the target class name

257

*/

258

ClassName getTarget(RegisteredBean registeredBean);

259

260

/**

261

* Generate the instance supplier code.

262

* @param generationContext the generation context

263

* @param beanRegistrationCode the bean registration code

264

* @param instanceSupplierCode the instance supplier code

265

* @return the generated instance supplier code

266

*/

267

CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,

268

BeanRegistrationCode beanRegistrationCode,

269

CodeBlock instanceSupplierCode);

270

271

/**

272

* Generate the return statement for the bean registration method.

273

* @param generationContext the generation context

274

* @param beanRegistrationCode the bean registration code

275

* @return the generated return statement

276

*/

277

CodeBlock generateReturnStatement(GenerationContext generationContext,

278

BeanRegistrationCode beanRegistrationCode);

279

280

/**

281

* Generate the set bean definition properties code.

282

* @param generationContext the generation context

283

* @param beanRegistrationCode the bean registration code

284

* @param assignedVariable the assigned variable name

285

* @param beanDefinition the bean definition

286

* @return the generated properties code

287

*/

288

CodeBlock generateSetBeanDefinitionPropertiesCode(GenerationContext generationContext,

289

BeanRegistrationCode beanRegistrationCode,

290

CodeBlock assignedVariable,

291

BeanDefinition beanDefinition);

292

293

/**

294

* Generate the set bean instance supplier code.

295

* @param generationContext the generation context

296

* @param beanRegistrationCode the bean registration code

297

* @param assignedVariable the assigned variable name

298

* @param instanceSupplierCode the instance supplier code

299

* @return the generated instance supplier code

300

*/

301

CodeBlock generateSetBeanInstanceSupplierCode(GenerationContext generationContext,

302

BeanRegistrationCode beanRegistrationCode,

303

CodeBlock assignedVariable,

304

CodeBlock instanceSupplierCode);

305

}

306

307

/**

308

* A BeanRegistrationCodeFragments decorator implementation.

309

*/

310

class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationCodeFragments {

311

/**

312

* Create a new BeanRegistrationCodeFragmentsDecorator.

313

* @param delegate the delegate to use

314

*/

315

public BeanRegistrationCodeFragmentsDecorator(BeanRegistrationCodeFragments delegate);

316

317

/**

318

* Return the target class name for the given registered bean.

319

* @param registeredBean the registered bean

320

* @return the target class name

321

*/

322

public ClassName getTarget(RegisteredBean registeredBean);

323

324

/**

325

* Generate the instance supplier code.

326

* @param generationContext the generation context

327

* @param beanRegistrationCode the bean registration code

328

* @param instanceSupplierCode the instance supplier code

329

* @return the generated instance supplier code

330

*/

331

public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,

332

BeanRegistrationCode beanRegistrationCode,

333

CodeBlock instanceSupplierCode);

334

335

/**

336

* Generate the return statement for the bean registration method.

337

* @param generationContext the generation context

338

* @param beanRegistrationCode the bean registration code

339

* @return the generated return statement

340

*/

341

public CodeBlock generateReturnStatement(GenerationContext generationContext,

342

BeanRegistrationCode beanRegistrationCode);

343

344

/**

345

* Generate the set bean definition properties code.

346

* @param generationContext the generation context

347

* @param beanRegistrationCode the bean registration code

348

* @param assignedVariable the assigned variable name

349

* @param beanDefinition the bean definition

350

* @return the generated properties code

351

*/

352

public CodeBlock generateSetBeanDefinitionPropertiesCode(GenerationContext generationContext,

353

BeanRegistrationCode beanRegistrationCode,

354

CodeBlock assignedVariable,

355

BeanDefinition beanDefinition);

356

357

/**

358

* Generate the set bean instance supplier code.

359

* @param generationContext the generation context

360

* @param beanRegistrationCode the bean registration code

361

* @param assignedVariable the assigned variable name

362

* @param instanceSupplierCode the instance supplier code

363

* @return the generated instance supplier code

364

*/

365

public CodeBlock generateSetBeanInstanceSupplierCode(GenerationContext generationContext,

366

BeanRegistrationCode beanRegistrationCode,

367

CodeBlock assignedVariable,

368

CodeBlock instanceSupplierCode);

369

}

370

```

371

372

### Code Warnings and Deprecation Support

373

374

Support for tracking and suppressing warnings in generated code.

375

376

```java { .api }

377

/**

378

* Utility class for tracking and managing code warnings during AOT processing.

379

*/

380

class CodeWarnings {

381

/**

382

* Create a new CodeWarnings instance.

383

*/

384

public CodeWarnings();

385

386

/**

387

* Register a warning message.

388

* @param warning the warning message

389

*/

390

public void register(String warning);

391

392

/**

393

* Detect deprecation warnings for the given annotated elements.

394

* @param elements the annotated elements to check

395

* @return this CodeWarnings instance for method chaining

396

*/

397

public CodeWarnings detectDeprecation(AnnotatedElement... elements);

398

399

/**

400

* Detect deprecation warnings for the given stream of annotated elements.

401

* @param elements the stream of annotated elements to check

402

* @return this CodeWarnings instance for method chaining

403

*/

404

public CodeWarnings detectDeprecation(Stream<AnnotatedElement> elements);

405

406

/**

407

* Detect deprecation warnings for the given resolvable type.

408

* @param resolvableType the resolvable type to check

409

* @return this CodeWarnings instance for method chaining

410

*/

411

public CodeWarnings detectDeprecation(ResolvableType resolvableType);

412

413

/**

414

* Suppress warnings on the given method specification builder.

415

* @param method the method specification builder

416

*/

417

public void suppress(MethodSpec.Builder method);

418

419

/**

420

* Suppress warnings on the given type specification builder.

421

* @param type the type specification builder

422

*/

423

public void suppress(TypeSpec.Builder type);

424

425

/**

426

* Check if there are any warnings registered.

427

* @return true if there are warnings

428

*/

429

public boolean hasWarnings();

430

431

/**

432

* Return a string representation of all warnings.

433

* @return the warnings as a string

434

*/

435

public String toString();

436

}

437

```

438

439

### Bean Registration Exclusion Filter

440

441

Interface for excluding beans from AOT processing.

442

443

```java { .api }

444

/**

445

* Filter that can be used to exclude bean definitions from AOT processing.

446

*/

447

interface BeanRegistrationExcludeFilter {

448

/**

449

* Determine if the given registered bean should be excluded from AOT processing.

450

* @param registeredBean the registered bean to check

451

* @return true if the bean should be excluded from AOT processing

452

*/

453

boolean isExcluded(RegisteredBean registeredBean);

454

}

455

```

456

457

### AOT Exception Handling

458

459

Exception classes for AOT processing errors.

460

461

```java { .api }

462

/**

463

* Abstract base class for AOT processing related exceptions.

464

*/

465

abstract class AotException extends RuntimeException {

466

/**

467

* Create a new AotException with the specified message.

468

* @param msg the detail message

469

*/

470

public AotException(String msg);

471

472

/**

473

* Create a new AotException with the specified message and root cause.

474

* @param msg the detail message

475

* @param cause the root cause

476

*/

477

public AotException(String msg, Throwable cause);

478

}

479

480

/**

481

* Exception thrown when AOT processing fails.

482

*/

483

class AotProcessingException extends AotException {

484

/**

485

* Create a new AotProcessingException with the specified message.

486

* @param msg the detail message

487

*/

488

public AotProcessingException(String msg);

489

490

/**

491

* Create a new AotProcessingException with the specified message and root cause.

492

* @param msg the detail message

493

* @param cause the root cause

494

*/

495

public AotProcessingException(String msg, Throwable cause);

496

}

497

498

/**

499

* Exception thrown when bean processing fails during AOT.

500

*/

501

class AotBeanProcessingException extends AotException {

502

private final RootBeanDefinition beanDefinition;

503

504

/**

505

* Create a new AotBeanProcessingException for the given bean definition.

506

* @param beanDefinition the bean definition that failed processing

507

* @param msg the detail message

508

*/

509

public AotBeanProcessingException(RootBeanDefinition beanDefinition, String msg);

510

511

/**

512

* Create a new AotBeanProcessingException for the given bean definition.

513

* @param beanDefinition the bean definition that failed processing

514

* @param msg the detail message

515

* @param cause the root cause

516

*/

517

public AotBeanProcessingException(RootBeanDefinition beanDefinition, String msg, Throwable cause);

518

519

/**

520

* Return the bean definition that failed processing.

521

* @return the bean definition

522

*/

523

public RootBeanDefinition getBeanDefinition();

524

}

525

```

526

527

**Usage Examples:**

528

529

```java

530

import org.springframework.aot.generate.GenerationContext;

531

import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;

532

import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;

533

import org.springframework.beans.factory.support.RegisteredBean;

534

535

// Custom AOT processor example

536

public class CustomBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {

537

538

@Override

539

public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {

540

// Only process beans of specific types

541

if (!isProcessable(registeredBean)) {

542

return null;

543

}

544

545

return new CustomBeanRegistrationAotContribution(registeredBean);

546

}

547

548

private boolean isProcessable(RegisteredBean registeredBean) {

549

Class<?> beanClass = registeredBean.getBeanClass();

550

return MyProcessableInterface.class.isAssignableFrom(beanClass);

551

}

552

553

private static class CustomBeanRegistrationAotContribution implements BeanRegistrationAotContribution {

554

private final RegisteredBean registeredBean;

555

556

public CustomBeanRegistrationAotContribution(RegisteredBean registeredBean) {

557

this.registeredBean = registeredBean;

558

}

559

560

@Override

561

public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {

562

// Generate custom initialization code

563

CodeBlock customCode = CodeBlock.builder()

564

.addStatement("$T bean = $L", registeredBean.getBeanClass(), "instanceSupplier.get()")

565

.addStatement("bean.initializeForAot()")

566

.addStatement("return bean")

567

.build();

568

569

// Apply the custom code to the registration

570

beanRegistrationCode.getInstanceSupplierCodeGenerator().addCode(customCode);

571

}

572

}

573

}

574

575

// Bean factory initialization AOT processor example

576

public class CustomBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor {

577

578

@Override

579

public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {

580

// Check if we need to contribute initialization code

581

if (!needsCustomInitialization(beanFactory)) {

582

return null;

583

}

584

585

return new CustomBeanFactoryInitializationAotContribution();

586

}

587

588

private boolean needsCustomInitialization(ConfigurableListableBeanFactory beanFactory) {

589

// Check for specific beans or configuration that requires custom initialization

590

return beanFactory.containsBean("customConfigurationBean");

591

}

592

593

private static class CustomBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotContribution {

594

595

@Override

596

public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) {

597

// Generate custom bean factory initialization code

598

MethodSpec initMethod = MethodSpec.methodBuilder("initializeCustomConfiguration")

599

.addModifiers(Modifier.PRIVATE, Modifier.STATIC)

600

.addParameter(ConfigurableListableBeanFactory.class, "beanFactory")

601

.addStatement("// Custom initialization logic here")

602

.addStatement("$T customBean = beanFactory.getBean($S, $T.class)",

603

CustomConfigBean.class, "customConfigurationBean", CustomConfigBean.class)

604

.addStatement("customBean.performAotInitialization()")

605

.build();

606

607

beanFactoryInitializationCode.getTypeBuilder().addMethod(initMethod);

608

}

609

}

610

}

611

612

// Bean exclusion filter example

613

public class CustomBeanRegistrationExcludeFilter implements BeanRegistrationExcludeFilter {

614

615

@Override

616

public boolean isExcluded(RegisteredBean registeredBean) {

617

// Exclude prototype beans from AOT processing

618

if (registeredBean.getBeanDefinition().isPrototype()) {

619

return true;

620

}

621

622

// Exclude beans with specific annotations

623

Class<?> beanClass = registeredBean.getBeanClass();

624

if (beanClass.isAnnotationPresent(ExcludeFromAot.class)) {

625

return true;

626

}

627

628

// Exclude test-related beans

629

String packageName = beanClass.getPackage().getName();

630

if (packageName.contains(".test.") || packageName.endsWith(".test")) {

631

return true;

632

}

633

634

return false;

635

}

636

}

637

638

// Custom annotation for excluding beans from AOT

639

@Target(ElementType.TYPE)

640

@Retention(RetentionPolicy.RUNTIME)

641

@Documented

642

public @interface ExcludeFromAot {

643

String reason() default "";

644

}

645

646

// Usage in Spring configuration

647

@Configuration

648

public class AotProcessingConfiguration {

649

650

@Bean

651

public BeanRegistrationAotProcessor customBeanRegistrationAotProcessor() {

652

return new CustomBeanRegistrationAotProcessor();

653

}

654

655

@Bean

656

public BeanFactoryInitializationAotProcessor customBeanFactoryInitializationAotProcessor() {

657

return new CustomBeanFactoryInitializationAotProcessor();

658

}

659

660

@Bean

661

public BeanRegistrationExcludeFilter customBeanRegistrationExcludeFilter() {

662

return new CustomBeanRegistrationExcludeFilter();

663

}

664

}

665

```

666

667

### Code Generation Utilities

668

669

Utilities for working with code generation during AOT processing.

670

671

```java { .api }

672

/**

673

* Enumeration of different sources for AOT processing.

674

*/

675

enum Source {

676

/** Source from Spring factories. */

677

SPRING_FACTORIES,

678

/** Source from bean factory. */

679

BEAN_FACTORY;

680

681

/**

682

* Create a loader for Spring factories.

683

* @return the loader

684

*/

685

public static Loader factories();

686

687

/**

688

* Create a loader for Spring factories with a specific ClassLoader.

689

* @param classLoader the ClassLoader to use

690

* @return the loader

691

*/

692

public static Loader factories(ClassLoader classLoader);

693

694

/**

695

* Create a loader for Spring factories with a specific SpringFactoriesLoader.

696

* @param springFactoriesLoader the SpringFactoriesLoader to use

697

* @return the loader

698

*/

699

public static Loader factories(SpringFactoriesLoader springFactoriesLoader);

700

701

/**

702

* Create a loader for both Spring factories and beans.

703

* @param beanFactory the bean factory

704

* @return the loader

705

*/

706

public static Loader factoriesAndBeans(ListableBeanFactory beanFactory);

707

708

/**

709

* Create a loader for both Spring factories and beans.

710

* @param springFactoriesLoader the SpringFactoriesLoader to use

711

* @param beanFactory the bean factory

712

* @return the loader

713

*/

714

public static Loader factoriesAndBeans(SpringFactoriesLoader springFactoriesLoader, ListableBeanFactory beanFactory);

715

716

/**

717

* Loader interface for loading instances from different sources.

718

*/

719

interface Loader<T> extends Iterable<T> {

720

/**

721

* Return an iterator over the loaded instances.

722

* @return the iterator

723

*/

724

Iterator<T> iterator();

725

726

/**

727

* Return a stream of the loaded instances.

728

* @return the stream

729

*/

730

Stream<T> stream();

731

732

/**

733

* Return the loaded instances as a list.

734

* @return the list of instances

735

*/

736

List<T> asList();

737

}

738

739

/** The location of the AOT factories resource. */

740

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring/aot.factories";

741

}

742

```