package org.springframework.beans.factory.annotation;
org.springframework.beans.factory.config.BeanPostProcessor implementation
that autowires annotated fields, setter methods and arbitrary config methods.
Such members to be injected are detected through a Java 5 annotation:
by default, Spring's
Autowired annotation.
Only one constructor (at max) of any given bean class may carry this
annotation with the 'required' parameter set to true,
indicating the constructor to autowire when used as a Spring bean.
If multiple non-required constructors carry the annotation, they
will be considered as candidates for autowiring. The constructor with
the greatest number of dependencies that can be satisfied by matching
beans in the Spring container will be chosen. If none of the candidates
can be satisfied, then a default constructor (if present) will be used.
An annotated constructor does not have to be public.
Fields are injected right after construction of a bean, before any
config methods are invoked. Such a config field does not have to be public.
Config methods may have an arbitrary name and any number of arguments;
each of those arguments will be autowired with a matching bean in the
Spring container. Bean property setter methods are effectively just
a special case of such a general config method. Such config methods
do not have to be public.
Note: A default AutowiredAnnotationBeanPostProcessor will be registered
by the "context:annotation-config" and "context:component-scan" XML tags.
Remove or turn off the default annotation configuration there if you intend
to specify a custom AutowiredAnnotationBeanPostProcessor bean definition.
- Author(s):
- Juergen Hoeller
- Mark Fisher
- Since:
- 2.5
- See also:
- setAutowiredAnnotationType
Autowiredorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor
private int order = Ordered.LOWEST_PRECEDENCE - 2;
Set the 'autowired' annotation type, to be used on constructors, fields,
setter methods and arbitrary config methods.
The default autowired annotation type is the Spring-provided
Autowired annotation.
This setter property exists so that developers can provide their own
(non-Spring-specific) annotation type to indicate that a member is
supposed to be autowired.
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
this.autowiredAnnotationType = autowiredAnnotationType;
Return the 'autowired' annotation type.
return this.autowiredAnnotationType;
Set the name of a parameter of the annotation that specifies
whether it is required.
this.requiredParameterName = requiredParameterName;
Set the boolean value that marks a dependency as required
For example if using 'required=true' (the default),
this value should be true; but if using
'optional=false', this value should be false.
this.requiredParameterValue = requiredParameterValue;
"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
Constructor[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) { synchronized (this.candidateConstructorsCache) { candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) { for (int i = 0; i < rawCandidates.length; i++) { if (annotation != null) { if (requiredConstructor != null) { ". Found another constructor with 'required' Autowired annotation: " + requiredConstructor);
". Found another constructor with 'required' Autowired annotation: " + requiredConstructor);
requiredConstructor = candidate;
candidates.add(candidate);
defaultConstructor = candidate;
if (requiredConstructor == null && defaultConstructor != null) { candidates.add(defaultConstructor);
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
return (candidateConstructors.length > 0 ? candidateConstructors : null);
'Native' processing method for direct calls with an arbitrary target
instance, resolving all of its fields and methods which are annotated
with
@Autowired.
- Parameters:
bean the target instance to process
synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(clazz);
if (annotation != null) { this.injectionMetadataCache.put(clazz, metadata);
Obtain all beans of the given type as autowire candidates.
if (this.beanFactory == null) { "override the getBeanOfType method or specify the 'beanFactory' property");
Determine if the annotated field or method requires its dependency.
A 'required' dependency means that autowiring should fail when no beans
are found. Otherwise, the autowiring process will simply bypass the field
or method when no beans are found.
- Parameters:
annotation the Autowired annotation- Returns:
- whether the annotation indicates that a dependency is required
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
Register the specified bean as dependent on the autowired beans.
logger.debug("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'");
Class representing injection information about an annotated field.
private volatile boolean cached = false;
this.required = required;
Field field = (Field) this.member;
value = beanFactory.getBean(((RuntimeBeanReference) this.cachedFieldValue).getBeanName());
value = this.cachedFieldValue;
this.cachedFieldValue = descriptor;
value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
if (autowiredBeanNames.size() == 1) { this.cachedFieldValue = null;
Class representing injection information about an annotated method.
private volatile boolean cached = false;
this.required = required;
if (this.skip == null && this.pd != null && pvs != null && pvs.contains(this.pd.getName())) { this.skip = Boolean.TRUE;
Method method = (Method) this.member;
if (this.cachedMethodArguments != null) { arguments = new Object[this.cachedMethodArguments.length];
for (int i = 0; i < arguments.length; i++) { Object cachedArg = this.cachedMethodArguments[i];
arguments[i] = beanFactory.resolveDependency(descriptor, beanName, null, typeConverter);
arguments[i] = cachedArg;
arguments = new Object[paramTypes.length];
this.cachedMethodArguments = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) { this.cachedMethodArguments[i] = descriptor;
descriptor, beanName, autowiredBeanNames, typeConverter);
if (arguments[i] == null) { if (autowiredBeanNames.size() == paramTypes.length) { for (int i = 0; i < paramTypes.length; i++) { if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { this.cachedMethodArguments[i] = arguments[i];
this.cachedMethodArguments = null;
this.skip = Boolean.FALSE;
method.invoke(bean, arguments);