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

annotation-config.mddocs/

0

# Annotation-Based Configuration

1

2

Comprehensive annotation support for dependency injection, lifecycle callbacks, and bean configuration with automatic detection and processing. This system enables declarative configuration through annotations, reducing the need for XML configuration files.

3

4

## Capabilities

5

6

### Core Dependency Injection Annotations

7

8

Essential annotations for marking injection points and configuring dependency injection behavior.

9

10

```java { .api }

11

/**

12

* Marks a constructor, field, setter method, or config method as to be autowired by Spring's dependency injection facilities.

13

*/

14

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

15

@Retention(RetentionPolicy.RUNTIME)

16

@Documented

17

@interface Autowired {

18

/**

19

* Declares whether the annotated dependency is required.

20

* @return whether the annotated dependency is required

21

*/

22

boolean required() default true;

23

}

24

25

/**

26

* This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring.

27

*/

28

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})

29

@Retention(RetentionPolicy.RUNTIME)

30

@Inherited

31

@Documented

32

@interface Qualifier {

33

/**

34

* The qualifier value for the annotated element.

35

* @return the qualifier value

36

*/

37

String value() default "";

38

}

39

40

/**

41

* Annotation used at the field or method/constructor parameter level that indicates a default value expression for the annotated element.

42

*/

43

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})

44

@Retention(RetentionPolicy.RUNTIME)

45

@Documented

46

@interface Value {

47

/**

48

* The actual value expression such as "#{systemProperties.myProp}" or property placeholder such as "${my.app.myProp}".

49

* @return the value expression

50

*/

51

String value();

52

}

53

54

/**

55

* Annotation at the method or type level that indicates that a method should be treated as a factory method.

56

*/

57

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})

58

@Retention(RetentionPolicy.RUNTIME)

59

@Documented

60

@interface Lookup {

61

/**

62

* This annotation attribute may be used to specify the name of the target bean to look up.

63

* @return the name of the target bean to look up

64

*/

65

String value() default "";

66

}

67

```

68

69

### Bean Configuration Annotations

70

71

Annotations for configuring how beans should be created and managed by the Spring container.

72

73

```java { .api }

74

/**

75

* Marks a class as providing configuration to the container using Spring 2.5's annotation-based container configuration.

76

*/

77

@Target(ElementType.TYPE)

78

@Retention(RetentionPolicy.RUNTIME)

79

@Documented

80

@interface Configurable {

81

/**

82

* The name of the bean definition that serves as the configuration template.

83

* @return the name of the bean definition to use as template

84

*/

85

String value() default "";

86

87

/**

88

* Are dependencies to be injected via autowiring?

89

* @return the autowire mode as defined in the Autowire enum

90

*/

91

Autowire autowire() default Autowire.NO;

92

93

/**

94

* Is dependency checking to be performed for configured objects?

95

* @return whether to apply dependency checking

96

*/

97

boolean dependencyCheck() default false;

98

99

/**

100

* Are dependencies to be injected prior to the construction of an object?

101

* @return whether to apply pre-construction injection

102

*/

103

boolean preConstruction() default false;

104

}

105

106

/**

107

* Enumeration used to determine the autowiring strategy.

108

*/

109

enum Autowire {

110

/** Constant that indicates no autowiring at all. */

111

NO(AutowireCapableBeanFactory.AUTOWIRE_NO),

112

113

/** Constant that indicates autowiring by name. */

114

BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),

115

116

/** Constant that indicates autowiring by type. */

117

BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);

118

119

private final int value;

120

121

Autowire(int value) {

122

this.value = value;

123

}

124

125

/**

126

* Return the integer value of this autowiring strategy.

127

* @return the integer value

128

*/

129

public int value() {

130

return this.value;

131

}

132

133

/**

134

* Return whether this represents an actual autowiring value.

135

* @return whether this represents actual autowiring

136

*/

137

public boolean isAutowire() {

138

return (this == BY_NAME || this == BY_TYPE);

139

}

140

}

141

```

142

143

### Autowired Annotation Processor

144

145

Bean post-processor that processes @Autowired, @Value, and other injection annotations.

146

147

```java { .api }

148

/**

149

* BeanPostProcessor implementation that autowires annotated fields, setter methods, and arbitrary config methods.

150

*/

151

class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, BeanFactoryAware, Ordered {

152

/**

153

* Create a new AutowiredAnnotationBeanPostProcessor for Spring's standard @Autowired and @Value annotations.

154

*/

155

public AutowiredAnnotationBeanPostProcessor();

156

157

/**

158

* Set the 'autowired' annotation type, to be used on constructors, fields, setter methods, and arbitrary config methods.

159

* @param autowiredAnnotationType the autowired annotation type

160

*/

161

public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType);

162

163

/**

164

* Set the 'autowired' annotation types, to be used on constructors, fields, setter methods, and arbitrary config methods.

165

* @param autowiredAnnotationTypes the autowired annotation types

166

*/

167

public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes);

168

169

/**

170

* Set the name of an attribute of the annotation that specifies whether it is required.

171

* @param requiredParameterName the name of the required parameter

172

*/

173

public void setRequiredParameterName(String requiredParameterName);

174

175

/**

176

* Set the boolean value that marks a dependency as required.

177

* @param requiredParameterValue the required parameter value

178

*/

179

public void setRequiredParameterValue(boolean requiredParameterValue);

180

181

/**

182

* Set the order value of this processor.

183

* @param order the order value

184

*/

185

public void setOrder(int order);

186

187

/**

188

* Return the order value of this processor.

189

* @return the order value

190

*/

191

public int getOrder();

192

193

/**

194

* Set the BeanFactory to use for looking up beans.

195

* @param beanFactory the BeanFactory to use

196

*/

197

public void setBeanFactory(BeanFactory beanFactory);

198

199

/**

200

* Post-process the given merged bean definition for the specified bean.

201

* @param beanDefinition the merged bean definition for the bean

202

* @param beanType the actual type of the managed bean instance

203

* @param beanName the name of the bean

204

*/

205

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

206

207

/**

208

* Reset the cached metadata for the given bean name.

209

* @param beanName the name of the bean

210

*/

211

public void resetBeanDefinition(String beanName);

212

213

/**

214

* Predict the eventual type of the processed bean instance.

215

* @param beanClass the raw class of the bean

216

* @param beanName the name of the bean

217

* @return the type of the bean, or null if not predictable

218

*/

219

public Class<?> predictBeanType(Class<?> beanClass, String beanName);

220

221

/**

222

* Determine candidate constructors to use for the given bean.

223

* @param beanClass the raw class of the bean (never null)

224

* @param beanName the name of the bean

225

* @return the candidate constructors, or null if none specified

226

* @throws BeanCreationException in case of errors

227

*/

228

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeanCreationException;

229

230

/**

231

* Post-process the given property values before the factory applies them to the given bean.

232

* @param pvs the property values that the factory is about to apply (never null)

233

* @param bean the bean instance created, but whose properties have not yet been set

234

* @param beanName the name of the bean

235

* @return the actual property values to apply to the given bean (can be the passed-in PropertyValues instance), or null to skip property population

236

* @throws BeansException in case of errors

237

*/

238

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException;

239

}

240

```

241

242

### Qualifier Annotation Support

243

244

Support for custom qualifier annotations and qualifier-based autowiring resolution.

245

246

```java { .api }

247

/**

248

* AutowireCandidateResolver implementation that matches bean definition qualifiers against qualifier annotations on the field or parameter to be autowired.

249

*/

250

class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {

251

/** Value annotation type for matching against qualifier values. */

252

public static final Class<? extends Annotation> VALUE_ANNOTATION = Value.class;

253

254

/**

255

* Create a new QualifierAnnotationAutowireCandidateResolver for Spring's standard Qualifier annotation.

256

*/

257

public QualifierAnnotationAutowireCandidateResolver();

258

259

/**

260

* Create a new QualifierAnnotationAutowireCandidateResolver for the given qualifier annotation type.

261

* @param qualifierType the qualifier annotation to check for

262

*/

263

public QualifierAnnotationAutowireCandidateResolver(Class<? extends Annotation> qualifierType);

264

265

/**

266

* Create a new QualifierAnnotationAutowireCandidateResolver for the given qualifier annotation types.

267

* @param qualifierTypes the qualifier annotations to check for

268

*/

269

public QualifierAnnotationAutowireCandidateResolver(Set<Class<? extends Annotation>> qualifierTypes);

270

271

/**

272

* Register an additional qualifier annotation type.

273

* @param qualifierType the qualifier annotation to check for

274

*/

275

public void addQualifierType(Class<? extends Annotation> qualifierType);

276

277

/**

278

* Set the 'value' annotation type, to be used on fields, setter methods, and parameters as a qualifiying hint.

279

* @param valueAnnotationType the value annotation type

280

*/

281

public void setValueAnnotationType(Class<? extends Annotation> valueAnnotationType);

282

283

/**

284

* Determine whether the provided bean definition is an autowire candidate.

285

* @param bdHolder the bean definition including bean name and aliases

286

* @param descriptor the descriptor for the target method parameter or field

287

* @return whether the bean definition qualifies as autowire candidate

288

*/

289

public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor);

290

291

/**

292

* Determine whether the given dependency declares a required annotation.

293

* @param descriptor the descriptor for the target method parameter or field

294

* @return whether the dependency declares a required annotation

295

*/

296

public boolean isRequired(DependencyDescriptor descriptor);

297

298

/**

299

* Determine whether the given dependency declares a qualifier annotation.

300

* @param descriptor the descriptor for the target method parameter or field

301

* @return whether the dependency declares a qualifier annotation

302

*/

303

public boolean hasQualifier(DependencyDescriptor descriptor);

304

305

/**

306

* Determine a suggested name for the given dependency.

307

* @param descriptor the descriptor for the target method parameter or field

308

* @return a suggested name (may be null if none found)

309

*/

310

public String getSuggestedName(DependencyDescriptor descriptor);

311

312

/**

313

* Determine a suggested value for the given dependency.

314

* @param descriptor the descriptor for the target method parameter or field

315

* @return a suggested value (may be null if none found)

316

*/

317

public Object getSuggestedValue(DependencyDescriptor descriptor);

318

}

319

```

320

321

### Injection Metadata Support

322

323

Infrastructure for managing and processing injection points discovered through annotation scanning.

324

325

```java { .api }

326

/**

327

* Internal class for managing injection metadata.

328

*/

329

class InjectionMetadata {

330

/** Empty metadata instance shared for efficiency. */

331

public static final InjectionMetadata EMPTY = new InjectionMetadata(Object.class, Collections.emptyList());

332

333

/**

334

* Create a new InjectionMetadata instance.

335

* @param targetClass the target class

336

* @param elements the associated elements to inject

337

*/

338

public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements);

339

340

/**

341

* Determine if this metadata instance has any injection elements.

342

* @return whether this metadata instance has any injection elements

343

*/

344

public boolean needsRefresh();

345

346

/**

347

* Mark the specified elements as externally managed configuration members.

348

* @param beanDefinition the bean definition to mark up

349

*/

350

public void checkConfigMembers(RootBeanDefinition beanDefinition);

351

352

/**

353

* Inject the configured resources into the given target bean.

354

* @param target the target bean

355

* @param beanName the name of the target bean

356

* @param pvs the property values (can be null)

357

* @throws Throwable if injection failed

358

*/

359

public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable;

360

361

/**

362

* Clear property skipping for the contained elements.

363

* @param pvs the property values (can be null)

364

*/

365

public void clear(PropertyValues pvs);

366

367

/**

368

* Return all InjectedElements held by this metadata instance.

369

* @return the injected elements (possibly empty, but never null)

370

*/

371

public Collection<InjectedElement> getInjectedElements();

372

373

/**

374

* Return all InjectedElements held by this metadata instance that are not present as property values.

375

* @param pvs the property values (can be null)

376

* @return the injected elements (possibly empty, but never null)

377

*/

378

public Collection<InjectedElement> getInjectedElements(PropertyValues pvs);

379

380

/**

381

* Build an InjectionMetadata instance from the given target class and element collection.

382

* @param elements the elements to include

383

* @param clazz the target class

384

* @return the injection metadata instance

385

*/

386

public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz);

387

388

/**

389

* Check whether the given injection metadata needs to be refreshed.

390

* @param metadata the existing metadata instance

391

* @param clazz the current target class

392

* @return whether a refresh is needed

393

*/

394

public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz);

395

396

/**

397

* A single injected element.

398

*/

399

public abstract static class InjectedElement {

400

protected final Member member;

401

protected final boolean isField;

402

protected final PropertyDescriptor pd;

403

protected volatile Boolean skip;

404

405

/**

406

* Create a new InjectedElement.

407

* @param member the member to inject into

408

* @param pd the corresponding property descriptor, if any

409

*/

410

protected InjectedElement(Member member, PropertyDescriptor pd);

411

412

/**

413

* Return the member to inject into.

414

* @return the member

415

*/

416

public final Member getMember();

417

418

/**

419

* Return the class that declares the member to inject into.

420

* @return the declaring class

421

*/

422

protected final Class<?> getResourceType();

423

424

/**

425

* Check whether this element is externally managed.

426

* @param beanDefinition the bean definition to check against

427

*/

428

protected void checkResourceType(RootBeanDefinition beanDefinition);

429

430

/**

431

* Either this or inject() needs to be overridden.

432

* @param target the target instance

433

* @param requestingBeanName the name of the requesting bean

434

* @param pvs the property values

435

* @throws Throwable if injection failed

436

*/

437

protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable;

438

439

/**

440

* Clear the property skipping marker, if any.

441

* @param pvs the property values

442

*/

443

protected void clearPropertySkipping(PropertyValues pvs);

444

}

445

}

446

```

447

448

### Bean Wiring Info Resolution

449

450

Support for resolving wiring information for beans, particularly useful for aspect-driven dependency injection.

451

452

```java { .api }

453

/**

454

* Strategy interface to be implemented by objects that can resolve bean wiring information for a bean instance.

455

*/

456

interface BeanWiringInfoResolver {

457

/**

458

* Resolve the BeanWiringInfo for the given bean instance.

459

* @param beanInstance the bean instance to resolve info for

460

* @return the BeanWiringInfo for the given bean, or null if no information found

461

*/

462

BeanWiringInfo resolveWiringInfo(Object beanInstance);

463

}

464

465

/**

466

* Simple default implementation of the BeanWiringInfoResolver interface, looking for a bean with the same name as the fully-qualified class name.

467

*/

468

class ClassNameBeanWiringInfoResolver implements BeanWiringInfoResolver {

469

/**

470

* Resolve the BeanWiringInfo for the given bean instance.

471

* @param beanInstance the bean instance to resolve info for

472

* @return the BeanWiringInfo for the given bean

473

*/

474

public BeanWiringInfo resolveWiringInfo(Object beanInstance);

475

}

476

477

/**

478

* BeanWiringInfoResolver that uses the Configurable annotation to identify which classes need autowiring.

479

*/

480

class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver {

481

/**

482

* Resolve the BeanWiringInfo for the given bean instance.

483

* @param beanInstance the bean instance to resolve info for

484

* @return the BeanWiringInfo for the given bean, or null if the bean isn't configured for autowiring

485

*/

486

public BeanWiringInfo resolveWiringInfo(Object beanInstance);

487

}

488

```

489

490

**Usage Examples:**

491

492

```java

493

import org.springframework.beans.factory.annotation.Autowired;

494

import org.springframework.beans.factory.annotation.Qualifier;

495

import org.springframework.beans.factory.annotation.Value;

496

497

// Basic dependency injection

498

public class OrderService {

499

500

@Autowired

501

private PaymentService paymentService;

502

503

@Autowired

504

private OrderRepository orderRepository;

505

506

@Value("${order.timeout:30}")

507

private int timeout;

508

509

// Constructor injection (recommended)

510

@Autowired

511

public OrderService(PaymentService paymentService, OrderRepository orderRepository) {

512

this.paymentService = paymentService;

513

this.orderRepository = orderRepository;

514

}

515

516

// Setter injection

517

@Autowired

518

public void setPaymentService(PaymentService paymentService) {

519

this.paymentService = paymentService;

520

}

521

522

// Method injection with multiple parameters

523

@Autowired

524

public void configure(PaymentService paymentService,

525

@Qualifier("primary") OrderRepository orderRepository,

526

@Value("${order.max-retries:3}") int maxRetries) {

527

this.paymentService = paymentService;

528

this.orderRepository = orderRepository;

529

this.maxRetries = maxRetries;

530

}

531

}

532

533

// Qualifier usage

534

public class PaymentServiceConfiguration {

535

536

@Autowired

537

@Qualifier("creditCard")

538

private PaymentProcessor creditCardProcessor;

539

540

@Autowired

541

@Qualifier("paypal")

542

private PaymentProcessor paypalProcessor;

543

544

// Collection injection with qualifiers

545

@Autowired

546

@Qualifier("highPriority")

547

private List<NotificationService> highPriorityServices;

548

549

// Map injection with qualifiers

550

@Autowired

551

private Map<String, PaymentProcessor> paymentProcessors;

552

}

553

554

// Optional dependencies

555

public class OptionalDependencyExample {

556

557

@Autowired(required = false)

558

private Optional<CacheService> cacheService;

559

560

@Autowired(required = false)

561

private List<Plugin> plugins = new ArrayList<>();

562

563

public void doSomething() {

564

cacheService.ifPresent(cache -> cache.put("key", "value"));

565

plugins.forEach(Plugin::execute);

566

}

567

}

568

569

// Configuration with @Configurable for domain objects

570

@Configurable(preConstruction = true)

571

public class Order {

572

573

@Autowired

574

private AuditService auditService;

575

576

@Value("${order.default.currency:USD}")

577

private String defaultCurrency;

578

579

public Order() {

580

// Dependencies are injected before constructor completes

581

auditService.logOrderCreation(this);

582

}

583

}

584

585

// Custom qualifiers

586

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE})

587

@Retention(RetentionPolicy.RUNTIME)

588

@Qualifier

589

public @interface PaymentMethod {

590

String value() default "";

591

}

592

593

public class PaymentController {

594

595

@Autowired

596

@PaymentMethod("creditCard")

597

private PaymentProcessor processor;

598

}

599

```

600

601

### Lifecycle Annotation Support

602

603

Support for JSR-250 lifecycle annotations and custom lifecycle annotation processing.

604

605

```java { .api }

606

/**

607

* BeanPostProcessor implementation that supports common Java annotations out of the box.

608

*/

609

class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, BeanFactoryAware, Ordered {

610

/**

611

* Create a new InitDestroyAnnotationBeanPostProcessor instance.

612

*/

613

public InitDestroyAnnotationBeanPostProcessor();

614

615

/**

616

* Specify the init annotation to check for, indicating initialization methods to call after configuration of a bean.

617

* @param initAnnotationType the init annotation type

618

*/

619

public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType);

620

621

/**

622

* Add an init annotation to check for, indicating initialization methods to call after configuration of a bean.

623

* @param initAnnotationType the init annotation type to add

624

*/

625

public void addInitAnnotationType(Class<? extends Annotation> initAnnotationType);

626

627

/**

628

* Specify the destroy annotation to check for, indicating destruction methods to call when the context is shutting down.

629

* @param destroyAnnotationType the destroy annotation type

630

*/

631

public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType);

632

633

/**

634

* Add a destroy annotation to check for, indicating destruction methods to call when the context is shutting down.

635

* @param destroyAnnotationType the destroy annotation type to add

636

*/

637

public void addDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType);

638

639

/**

640

* Set the order value of this processor.

641

* @param order the order value

642

*/

643

public void setOrder(int order);

644

645

/**

646

* Return the order value of this processor.

647

* @return the order value

648

*/

649

public int getOrder();

650

651

/**

652

* Set the BeanFactory to use for looking up beans.

653

* @param beanFactory the BeanFactory to use

654

*/

655

public void setBeanFactory(BeanFactory beanFactory);

656

657

/**

658

* Post-process the given merged bean definition for the specified bean.

659

* @param beanDefinition the merged bean definition for the bean

660

* @param beanType the actual type of the managed bean instance

661

* @param beanName the name of the bean

662

*/

663

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

664

665

/**

666

* Reset the cached metadata for the given bean name.

667

* @param beanName the name of the bean

668

*/

669

public void resetBeanDefinition(String beanName);

670

671

/**

672

* Check whether the given bean definition specifies any initialization methods.

673

* @param beanDefinition the bean definition to check

674

*/

675

public void checkInitDestroyMethods(RootBeanDefinition beanDefinition);

676

677

/**

678

* Invoke the initialization methods on the given bean instance.

679

* @param target the target bean instance

680

* @param beanName the name of the bean

681

* @throws Throwable if initialization failed

682

*/

683

public void invokeInitMethods(Object target, String beanName) throws Throwable;

684

685

/**

686

* Invoke the destruction methods on the given bean instance.

687

* @param target the target bean instance

688

* @param beanName the name of the bean

689

* @throws Throwable if destruction failed

690

*/

691

public void invokeDestroyMethods(Object target, String beanName) throws Throwable;

692

693

/**

694

* Determine whether the given bean has any destroy methods.

695

* @return whether the bean has destroy methods

696

*/

697

public boolean hasDestroyMethods();

698

}

699

```

700

701

### Additional Dependency Injection Annotations

702

703

Extended annotation support for specialized injection scenarios and method-based dependencies.

704

705

```java { .api }

706

/**

707

* Annotation to be used on methods in a Spring application context for method injection scenarios.

708

*/

709

@Target(ElementType.METHOD)

710

@Retention(RetentionPolicy.RUNTIME)

711

@Documented

712

@interface Lookup {

713

/**

714

* This attribute may suggest a target bean name to look up.

715

* @return the suggested target bean name, if any (or empty String if none)

716

*/

717

String value() default "";

718

}

719

720

/**

721

* Marks a method as being 'required' - that is, it must be configured to be dependency-injected with a value.

722

*/

723

@Target(ElementType.METHOD)

724

@Retention(RetentionPolicy.RUNTIME)

725

@Documented

726

@interface Required {

727

}

728

```

729

730

### Bean Post-Processor Implementations

731

732

Concrete implementations of bean post-processors for handling annotations and injection.

733

734

```java { .api }

735

/**

736

* BeanPostProcessor implementation that processes @Autowired, @Value, and @Inject annotations.

737

*/

738

class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

739

/** The default autowired annotation types. */

740

public static final Set<Class<? extends Annotation>> AUTOWIRED_ANNOTATION_TYPES;

741

742

/**

743

* Create a new AutowiredAnnotationBeanPostProcessor for Spring's @Autowired and @Value annotations.

744

*/

745

public AutowiredAnnotationBeanPostProcessor();

746

747

/**

748

* Set the 'autowired' annotation type, to be used on constructors, fields, setter methods, and arbitrary config methods.

749

* @param autowiredAnnotationType the annotation type to check for

750

*/

751

public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType);

752

753

/**

754

* Set the 'autowired' annotation types, to be used on constructors, fields, setter methods, and arbitrary config methods.

755

* @param autowiredAnnotationTypes the annotation types to check for

756

*/

757

public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes);

758

759

/**

760

* Set the name of an attribute of the annotation that specifies whether it is required.

761

* @param requiredParameterName the name of the required attribute

762

*/

763

public void setRequiredParameterName(String requiredParameterName);

764

765

/**

766

* Set the value of the annotation attribute that specifies that a dependency is required.

767

* @param requiredParameterValue the required attribute value

768

*/

769

public void setRequiredParameterValue(boolean requiredParameterValue);

770

771

/**

772

* Set the order value of this object.

773

* @param order the order value

774

*/

775

public void setOrder(int order);

776

777

/**

778

* Return the order value of this object.

779

* @return the order value

780

*/

781

public int getOrder();

782

783

/**

784

* Set the BeanFactory to be used by this processor.

785

* @param beanFactory the BeanFactory

786

*/

787

public void setBeanFactory(BeanFactory beanFactory) throws BeansException;

788

789

/**

790

* This implementation processes @Autowired, @Value, and JSR-330 @Inject annotations.

791

* @param beanDefinition the merged bean definition for the bean

792

* @param beanType the actual type of the managed bean instance

793

* @param beanName the name of the bean

794

*/

795

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

796

797

/**

798

* This implementation resets the injection metadata if the bean definition changes.

799

* @param beanName the name of the bean

800

*/

801

public void resetBeanDefinition(String beanName);

802

803

/**

804

* This implementation returns candidate constructors.

805

* @param beanClass the raw class of the bean

806

* @param beanName the name of the bean

807

* @return the candidate constructors, or null if none

808

* @throws BeansException in case of errors

809

*/

810

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;

811

812

/**

813

* This implementation processes @Autowired, @Value, and @Inject annotations.

814

* @param pvs the property values that the factory is about to apply (never null)

815

* @param bean the bean instance created, but whose properties have not yet been set

816

* @param beanName the name of the bean

817

* @return the actual property values to apply to the given bean

818

* @throws BeansException in case of errors

819

*/

820

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException;

821

822

/**

823

* This implementation processes @Autowired annotations, checking whether the annotation is present on this post-processor's 'required' annotation list.

824

* @param pvs the property values that the factory is about to apply (never null)

825

* @param pds the relevant property descriptors for the target bean

826

* @param bean the bean instance created, but whose properties have not yet been set

827

* @param beanName the name of the bean

828

* @return the actual property values to apply to the given bean

829

* @throws BeansException in case of errors

830

* @deprecated as of 5.1, in favor of postProcessProperties

831

*/

832

@Deprecated

833

public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

834

}

835

836

/**

837

* Simple processor for JSR-250 style annotations: @PostConstruct, @PreDestroy, and @Resource.

838

*/

839

class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

840

/**

841

* Create a new CommonAnnotationBeanPostProcessor.

842

*/

843

public CommonAnnotationBeanPostProcessor();

844

845

/**

846

* Set the 'init' annotation type, to be used on lifecycle methods.

847

* @param initAnnotationType the annotation type to check for

848

*/

849

public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType);

850

851

/**

852

* Set the 'destroy' annotation type, to be used on lifecycle methods.

853

* @param destroyAnnotationType the annotation type to check for

854

*/

855

public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType);

856

857

/**

858

* Ignore the given resource type when resolving @Resource annotations.

859

* @param resourceType the resource type to ignore

860

*/

861

public void ignoreResourceType(String resourceType);

862

863

/**

864

* Set the BeanFactory to be used by this processor.

865

* @param beanFactory the BeanFactory

866

*/

867

public void setBeanFactory(BeanFactory beanFactory);

868

869

/**

870

* This implementation processes @Resource annotations.

871

* @param pvs the property values that the factory is about to apply (never null)

872

* @param bean the bean instance created, but whose properties have not yet been set

873

* @param beanName the name of the bean

874

* @return the actual property values to apply to the given bean

875

* @throws BeansException in case of errors

876

*/

877

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException;

878

879

/**

880

* This implementation processes @Resource annotations.

881

* @param pvs the property values that the factory is about to apply (never null)

882

* @param pds the relevant property descriptors for the target bean

883

* @param bean the bean instance created, but whose properties have not yet been set

884

* @param beanName the name of the bean

885

* @return the actual property values to apply to the given bean

886

* @throws BeansException in case of errors

887

* @deprecated as of 5.1, in favor of postProcessProperties

888

*/

889

@Deprecated

890

public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

891

}

892

893

/**

894

* Simple processor for methods annotated with @Required.

895

*/

896

class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

897

/**

898

* Bean post processor marker that indicates whether a bean's required properties have been checked.

899

*/

900

public static final String SKIP_REQUIRED_CHECK_ATTRIBUTE = RequiredAnnotationBeanPostProcessor.class.getName() + ".SKIP_REQUIRED_CHECK_ATTRIBUTE";

901

902

/**

903

* Create a new RequiredAnnotationBeanPostProcessor.

904

*/

905

public RequiredAnnotationBeanPostProcessor();

906

907

/**

908

* Set the 'required' annotation type, to be used on bean property setter methods.

909

* @param requiredAnnotationType the annotation type to check for

910

*/

911

public void setRequiredAnnotationType(Class<? extends Annotation> requiredAnnotationType);

912

913

/**

914

* Return the 'required' annotation type.

915

* @return the 'required' annotation type

916

*/

917

protected Class<? extends Annotation> getRequiredAnnotationType();

918

919

/**

920

* Set the order value of this object.

921

* @param order the order value

922

*/

923

public void setOrder(int order);

924

925

/**

926

* Return the order value of this object.

927

* @return the order value

928

*/

929

public int getOrder();

930

931

/**

932

* Set the BeanFactory to be used by this processor.

933

* @param beanFactory the BeanFactory

934

*/

935

public void setBeanFactory(BeanFactory beanFactory);

936

937

/**

938

* This implementation processes @Required annotations.

939

* @param beanDefinition the merged bean definition for the bean

940

* @param beanType the actual type of the managed bean instance

941

* @param beanName the name of the bean

942

*/

943

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

944

945

/**

946

* This implementation checks for @Required annotations.

947

* @param pvs the property values that the factory is about to apply (never null)

948

* @param pds the relevant property descriptors for the target bean

949

* @param bean the bean instance created, but whose properties have not yet been set

950

* @param beanName the name of the bean

951

* @return the actual property values to apply to the given bean (can be the passed-in PropertyValues instance)

952

* @throws BeansException in case of errors

953

* @deprecated as of 5.1, in favor of postProcessProperties

954

*/

955

@Deprecated

956

public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

957

}

958

```

959

960

### Injection Metadata Support

961

962

Classes that manage metadata about injection points and provide runtime injection support.

963

964

```java { .api }

965

/**

966

* Internal class for managing injection metadata.

967

*/

968

class InjectionMetadata {

969

/**

970

* An empty InjectionMetadata instance with no-op callbacks.

971

*/

972

public static final InjectionMetadata EMPTY = new InjectionMetadata(Object.class, Collections.emptyList());

973

974

/**

975

* Create a new InjectionMetadata instance.

976

* @param targetClass the target class

977

* @param injectedElements the (typically field and method) elements to inject

978

*/

979

public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> injectedElements);

980

981

/**

982

* Create a new InjectionMetadata instance.

983

* @param targetClass the target class

984

* @param injectedElements the (typically field and method) elements to inject

985

*/

986

public InjectionMetadata(Class<?> targetClass, InjectedElement... injectedElements);

987

988

/**

989

* Check configuration of this metadata.

990

* @param beanName the name of the bean

991

*/

992

public void checkConfigMembers(RootBeanDefinition beanDefinition);

993

994

/**

995

* Inject the configured elements into the given target bean.

996

* @param target the target bean

997

* @param beanName the name of the bean

998

* @param pvs the PropertyValues for the bean (may be null)

999

* @throws Throwable if injection failed

1000

*/

1001

public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable;

1002

1003

/**

1004

* Clear property skipping for the contained elements.

1005

*/

1006

public void clear(PropertyValues pvs);

1007

1008

/**

1009

* Check whether this injector has determined that it needs to skip the bean property with the given name.

1010

* @param pvs the PropertyValues to check

1011

* @param pd the PropertyDescriptor of the target property

1012

* @return whether this injector suggests skipping the property

1013

*/

1014

public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz);

1015

1016

/**

1017

* A single injected element.

1018

*/

1019

public abstract static class InjectedElement {

1020

/**

1021

* Create a new InjectedElement for the given member.

1022

* @param member the member

1023

* @param pd the PropertyDescriptor, if any

1024

*/

1025

protected InjectedElement(Member member, PropertyDescriptor pd);

1026

1027

/**

1028

* Return the annotation metadata.

1029

* @return the annotation metadata

1030

*/

1031

public final Member getMember();

1032

1033

/**

1034

* Return the related PropertyDescriptor if any.

1035

* @return the PropertyDescriptor, or null if none

1036

*/

1037

protected final PropertyDescriptor getPropertyDescriptor();

1038

1039

/**

1040

* Check whether this injector has determined that it needs to skip the bean property with the given name.

1041

* @param pvs the PropertyValues to check

1042

* @return whether this injector suggests skipping the property

1043

*/

1044

public boolean isSkipped(PropertyValues pvs);

1045

1046

/**

1047

* Either this or {inject} needs to be overridden.

1048

* @param target the target bean

1049

* @param beanName the name of the bean

1050

* @param pvs the PropertyValues for the bean

1051

* @throws Throwable if injection failed

1052

*/

1053

protected void inject(Object target, String beanName, PropertyValues pvs) throws Throwable;

1054

1055

/**

1056

* Either this or {inject} needs to be overridden.

1057

* @param beanDefinition the bean definition to check

1058

*/

1059

protected void checkResourceType(RootBeanDefinition beanDefinition);

1060

}

1061

}

1062

1063

/**

1064

* Descriptor for a specific dependency that is about to be injected.

1065

*/

1066

class DependencyDescriptor implements Serializable {

1067

/**

1068

* Create a new descriptor for a field.

1069

* @param field the field to wrap

1070

* @param required whether the dependency is required

1071

*/

1072

public DependencyDescriptor(Field field, boolean required);

1073

1074

/**

1075

* Create a new descriptor for a field.

1076

* @param field the field to wrap

1077

* @param required whether the dependency is required

1078

* @param eager whether this dependency is 'eager' in the sense of eagerly resolving potential target beans for type matching

1079

*/

1080

public DependencyDescriptor(Field field, boolean required, boolean eager);

1081

1082

/**

1083

* Create a new descriptor for a method or constructor parameter.

1084

* @param methodParameter the MethodParameter to wrap

1085

* @param required whether the dependency is required

1086

*/

1087

public DependencyDescriptor(MethodParameter methodParameter, boolean required);

1088

1089

/**

1090

* Create a new descriptor for a method or constructor parameter.

1091

* @param methodParameter the MethodParameter to wrap

1092

* @param required whether the dependency is required

1093

* @param eager whether this dependency is 'eager' in the sense of eagerly resolving potential target beans for type matching

1094

*/

1095

public DependencyDescriptor(MethodParameter methodParameter, boolean required, boolean eager);

1096

1097

/**

1098

* Copy constructor.

1099

* @param original the original descriptor to copy from

1100

*/

1101

public DependencyDescriptor(DependencyDescriptor original);

1102

1103

/**

1104

* Return whether this dependency is required.

1105

* @return whether this dependency is required

1106

*/

1107

public boolean isRequired();

1108

1109

/**

1110

* Return whether this dependency is 'eager' in the sense of eagerly resolving potential target beans for type matching.

1111

* @return whether this dependency is eager

1112

*/

1113

public boolean isEager();

1114

1115

/**

1116

* Resolve the specified not-unique scenario: by default, throwing a NoUniqueBeanDefinitionException.

1117

* @param type the requested bean type

1118

* @param matchingBeans a map of bean names and corresponding bean instances which have been pre-selected for the given type

1119

* @return a candidate bean name to proceed with

1120

* @throws BeansException in case of the not-unique scenario being fatal

1121

*/

1122

public Object resolveNotUnique(ResolvableType type, Map<String, Object> matchingBeans) throws BeansException;

1123

1124

/**

1125

* Resolve a shortcut for this dependency against the given factory.

1126

* @param beanFactory the BeanFactory to resolve against

1127

* @return the shortcut result if any, or null if none

1128

* @throws BeansException if the shortcut could not be obtained

1129

*/

1130

public Object resolveShortcut(AutowireCapableBeanFactory beanFactory) throws BeansException;

1131

1132

/**

1133

* Resolve this dependency against the given factory.

1134

* @param beanFactory the BeanFactory to resolve against

1135

* @return the resolved object, or null if not found

1136

* @throws BeansException if the dependency could not be resolved

1137

*/

1138

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException;

1139

1140

/**

1141

* Return the wrapped MethodParameter, if any.

1142

* @return the MethodParameter, or null if none

1143

*/

1144

public MethodParameter getMethodParameter();

1145

1146

/**

1147

* Return the wrapped Field, if any.

1148

* @return the Field, or null if none

1149

*/

1150

public Field getField();

1151

1152

/**

1153

* Return whether a fallback match is allowed.

1154

* @return whether a fallback match is allowed

1155

*/

1156

public boolean fallbackMatchAllowed();

1157

1158

/**

1159

* Return a variant of this descriptor that is intended for a fallback match.

1160

* @return the fallback descriptor (never null)

1161

*/

1162

public DependencyDescriptor forFallbackMatch();

1163

1164

/**

1165

* Initialize parameter name discovery for the underlying method parameter, if any.

1166

*/

1167

public void initParameterNameDiscovery(ParameterNameDiscoverer parameterNameDiscoverer);

1168

1169

/**

1170

* Determine the name of the wrapped parameter/field.

1171

* @return the declared name (may be null if unresolvable)

1172

*/

1173

public String getDependencyName();

1174

1175

/**

1176

* Determine the declared (non-generic) type of the wrapped parameter/field.

1177

* @return the declared type (never null)

1178

*/

1179

public Class<?> getDependencyType();

1180

1181

/**

1182

* Determine the generic type of the wrapped parameter/field.

1183

* @return the generic type (never null)

1184

*/

1185

public ResolvableType getResolvableType();

1186

1187

/**

1188

* Return whether the wrapped parameter/field expects a collection of elements.

1189

* @return whether a collection is expected

1190

*/

1191

public boolean isCollectionType();

1192

1193

/**

1194

* Return whether the wrapped parameter/field expects an array of elements.

1195

* @return whether an array is expected

1196

*/

1197

public boolean isArrayType();

1198

1199

/**

1200

* Return whether the wrapped parameter/field expects a map of elements.

1201

* @return whether a map is expected

1202

*/

1203

public boolean isMapType();

1204

1205

/**

1206

* Return whether the wrapped parameter/field expects an optional dependency.

1207

* @return whether an optional dependency is expected

1208

*/

1209

public boolean isOptional();

1210

}

1211

```

1212