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