Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2002-2009 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.springframework.beans.factory.annotation;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 
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.

Also supports JSR-330's javax.inject.Inject annotation, if available.

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.

NOTE: Annotation injection will be performed before XML injection; thus the latter configuration will override the former for properties wired through both approaches.

Author(s):
Juergen Hoeller
Mark Fisher
Since:
2.5
See also:
setAutowiredAnnotationType(java.lang.Class)
Autowired
	protected final Log logger = LogFactory.getLog(getClass());
	private final Set<Class<? extends Annotation>> autowiredAnnotationTypes =
			new LinkedHashSet<Class<? extends Annotation>>();
	private String requiredParameterName = "required";
	private boolean requiredParameterValue = true;
	private int order = . - 2;
	private final Map<Class<?>, Constructor[]> candidateConstructorsCache =
Create a new AutowiredAnnotationBeanPostProcessor for Spring's standard Autowired annotation.

Also supports JSR-330's javax.inject.Inject annotation, if available.

	@SuppressWarnings("unchecked")
		try {
			this..add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
			.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}


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, as well as Value.

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.

	public void setAutowiredAnnotationType(Class<? extends AnnotationautowiredAnnotationType) {
		Assert.notNull(autowiredAnnotationType"'autowiredAnnotationType' must not be null");
		this..add(autowiredAnnotationType);
	}

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

The default autowired annotation type is the Spring-provided Autowired annotation, as well as Value.

This setter property exists so that developers can provide their own (non-Spring-specific) annotation types to indicate that a member is supposed to be autowired.

	public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
		Assert.notEmpty(autowiredAnnotationTypes"'autowiredAnnotationTypes' must not be empty");
		this..addAll(autowiredAnnotationTypes);
	}

Set the name of a parameter of the annotation that specifies whether it is required.

	public void setRequiredParameterName(String requiredParameterName) {
		this. = 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.

	public void setRequiredParameterValue(boolean requiredParameterValue) {
		this. = requiredParameterValue;
	}
	public void setOrder(int order) {
	  this. = order;
	}
	public int getOrder() {
	  return this.;
	}
	public void setBeanFactory(BeanFactory beanFactorythrows BeansException {
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
					"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
		}
	}
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinitionClass beanTypeString beanName) {
		if (beanType != null) {
			metadata.checkConfigMembers(beanDefinition);
		}
	}
	public Constructor[] determineCandidateConstructors(Class beanClassString beanNamethrows BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		Constructor[] candidateConstructors = this..get(beanClass);
		if (candidateConstructors == null) {
			synchronized (this.) {
				candidateConstructors = this..get(beanClass);
				if (candidateConstructors == null) {
					Constructor[] rawCandidates = beanClass.getDeclaredConstructors();
					List<Constructorcandidates = new ArrayList<Constructor>(rawCandidates.length);
					Constructor requiredConstructor = null;
					Constructor defaultConstructor = null;
					for (Constructor<?> candidate : rawCandidates) {
						Annotation annotation = findAutowiredAnnotation(candidate);
						if (annotation != null) {
							if (requiredConstructor != null) {
								throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate +
										". Found another constructor with 'required' Autowired annotation: " +
										requiredConstructor);
							}
							if (candidate.getParameterTypes().length == 0) {
										"Autowired annotation requires at least one argument: " + candidate);
							}
							boolean required = determineRequiredStatus(annotation);
							if (required) {
								if (!candidates.isEmpty()) {
											"Invalid autowire-marked constructors: " + candidates +
											". Found another constructor with 'required' Autowired annotation: " +
											requiredConstructor);
								}
								requiredConstructor = candidate;
							}
							candidates.add(candidate);
						}
						else if (candidate.getParameterTypes().length == 0) {
							defaultConstructor = candidate;
						}
					}
					if (!candidates.isEmpty()) {
						// Add default constructor to list of optional constructors, as fallback.
						if (requiredConstructor == null && defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						candidateConstructors = candidates.toArray(new Constructor[candidates.size()]);
					}
					else {
						candidateConstructors = new Constructor[0];
					}
					this..put(beanClasscandidateConstructors);
				}
			}
		}
		return (candidateConstructors.length > 0 ? candidateConstructors : null);
	}
			PropertyValues pvsPropertyDescriptor[] pdsObject beanString beanNamethrows BeansException {
		try {
			metadata.inject(beanbeanNamepvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName"Injection of autowired dependencies failed"ex);
		}
		return pvs;
	}

'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
Throws:
org.springframework.beans.BeansException if autowiring failed
	public void processInjection(Object beanthrows BeansException {
		Class<?> clazz = bean.getClass();
		try {
			metadata.inject(beannullnull);
		}
		catch (Throwable ex) {
			throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]"ex);
		}
	}
		// Quick check on the concurrent map first, with minimal locking.
		InjectionMetadata metadata = this..get(clazz);
		if (metadata == null) {
			synchronized (this.) {
				metadata = this..get(clazz);
				if (metadata == null) {
					metadata = buildAutowiringMetadata(clazz);
					this..put(clazzmetadata);
				}
			}
		}
		return metadata;
	}
		Class<?> targetClass = clazz;
		do {
			for (Field field : targetClass.getDeclaredFields()) {
				Annotation annotation = findAutowiredAnnotation(field);
				if (annotation != null) {
					if (Modifier.isStatic(field.getModifiers())) {
							.warn("Autowired annotation is not supported on static fields: " + field);
						}
						continue;
					}
					boolean required = determineRequiredStatus(annotation);
					currElements.add(new AutowiredFieldElement(fieldrequired));
				}
			}
			for (Method method : targetClass.getDeclaredMethods()) {
				Annotation annotation = findAutowiredAnnotation(method);
				if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(methodclazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
							.warn("Autowired annotation is not supported on static methods: " + method);
						}
						continue;
					}
					if (method.getParameterTypes().length == 0) {
							.warn("Autowired annotation should be used on methods with actual parameters: " + method);
						}
					}
					boolean required = determineRequiredStatus(annotation);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
					currElements.add(new AutowiredMethodElement(methodrequiredpd));
				}
			}
			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);
		return new InjectionMetadata(clazzelements);
	}
		for (Class<? extends Annotationtype : this.) {
			Annotation annotation = ao.getAnnotation(type);
			if (annotation != null) {
				return annotation;
			}
		}
		return null;
	}

Obtain all beans of the given type as autowire candidates.

Parameters:
type the type of the bean
Returns:
the target beans, or an empty Collection if no bean of this type is found
Throws:
org.springframework.beans.BeansException if bean retrieval failed
	protected <T> Map<String, T> findAutowireCandidates(Class<T> typethrows BeansException {
		if (this. == null) {
			throw new IllegalStateException("No BeanFactory configured - " +
					"override the getBeanOfType method or specify the 'beanFactory' property");
		}
		return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.type);
	}

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
	protected boolean determineRequiredStatus(Annotation annotation) {
		try {
			Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.);
			return (this. == (Boolean) ReflectionUtils.invokeMethod(methodannotation));
		}
		catch (Exception ex) {
			// required by default
			return true;
		}
	}

Register the specified bean as dependent on the autowired beans.
	private void registerDependentBeans(String beanNameSet<StringautowiredBeanNames) {
		if (beanName != null) {
			for (String autowiredBeanName : autowiredBeanNames) {
				.registerDependentBean(autowiredBeanNamebeanName);
							"Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName +
									"'");
				}
			}
		}
	}

Resolve the specified cached method argument or field value.
	private Object resolvedCachedArgument(String beanNameObject cachedArgument) {
		if (cachedArgument instanceof DependencyDescriptor) {
			DependencyDescriptor descriptor = (DependencyDescriptorcachedArgument;
			return .resolveDependency(descriptorbeanNamenulltypeConverter);
		}
		else if (cachedArgument instanceof RuntimeBeanReference) {
			return .getBean(((RuntimeBeanReferencecachedArgument).getBeanName());
		}
		else {
			return cachedArgument;
		}
	}


Class representing injection information about an annotated field.
		private final boolean required;
		private volatile boolean cached = false;
		private volatile Object cachedFieldValue;
		public AutowiredFieldElement(Field fieldboolean required) {
			super(fieldnull);
			this. = required;
		}
		protected void inject(Object beanString beanNamePropertyValues pvsthrows Throwable {
			Field field = (Fieldthis.;
			try {
				Object value;
				if (this.) {
					value = resolvedCachedArgument(beanNamethis.);
				}
				else {
					synchronized (this) {
						if (!this.) {
							Set<StringautowiredBeanNames = new LinkedHashSet<String>(1);
							DependencyDescriptor descriptor = new DependencyDescriptor(fieldthis.);
							this. = descriptor;
							value = .resolveDependency(descriptorbeanNameautowiredBeanNamestypeConverter);
							if (value != null) {
								registerDependentBeans(beanNameautowiredBeanNames);
								if (autowiredBeanNames.size() == 1) {
									String autowiredBeanName = autowiredBeanNames.iterator().next();
									if (.containsBean(autowiredBeanName)) {
										if (.isTypeMatch(autowiredBeanNamefield.getType())) {
											this. = new RuntimeBeanReference(autowiredBeanName);
										}
									}
								}
							}
							else {
								this. = null;
							}
							this. = true;
						}
						else {
							// Already cached in the meantime...
							value = resolvedCachedArgument(beanNamethis.);
						}
					}
				}
				if (value != null) {
					ReflectionUtils.makeAccessible(field);
					field.set(beanvalue);
				}
			}
			catch (Throwable ex) {
				throw new BeanCreationException("Could not autowire field: " + fieldex);
			}
		}
	}


Class representing injection information about an annotated method.
		private final boolean required;
		private volatile boolean cached = false;
		private volatile Object[] cachedMethodArguments;
		public AutowiredMethodElement(Method methodboolean requiredPropertyDescriptor pd) {
			super(methodpd);
			this. = required;
		}
		protected void inject(Object beanString beanNamePropertyValues pvsthrows Throwable {
			if (this. == null && this. != null && pvs != null && pvs.contains(this..getName())) {
				// Explicit value provided as part of the bean definition.
				this. = .;
			}
			if (this. != null && this.) {
				return;
			}
			Method method = (Methodthis.;
			try {
				Object[] arguments;
				if (this.) {
					// Shortcut for avoiding synchronization...
					arguments = resolveCachedArguments(beanName);
				}
				else {
					synchronized (this) {
						if (!this.) {
							Class[] paramTypes = method.getParameterTypes();
							arguments = new Object[paramTypes.length];
							Set<StringautowiredBeanNames = new LinkedHashSet<String>(arguments.length);
							this. = new Object[arguments.length];
							for (int i = 0; i < arguments.lengthi++) {
								MethodParameter methodParam = new MethodParameter(methodi);
								GenericTypeResolver.resolveParameterType(methodParambean.getClass());
								DependencyDescriptor descriptor = new DependencyDescriptor(methodParamthis.);
								this.[i] = descriptor;
										descriptorbeanNameautowiredBeanNamestypeConverter);
								if (arguments[i] == null) {
									arguments = null;
									break;
								}
							}
							if (arguments != null) {
								registerDependentBeans(beanNameautowiredBeanNames);
								if (autowiredBeanNames.size() == paramTypes.length) {
									Iterator<Stringit = autowiredBeanNames.iterator();
									for (int i = 0; i < paramTypes.lengthi++) {
										String autowiredBeanName = it.next();
										if (.containsBean(autowiredBeanName)) {
											if (.isTypeMatch(autowiredBeanNameparamTypes[i])) {
												this.[i] = new RuntimeBeanReference(autowiredBeanName);
											}
										}
										else {
											this.[i] = arguments[i];
										}
									}
								}
							}
							else {
								this. = null;
							}
							this. = true;
						}
						else {
							// Already cached in the meantime...
							arguments = resolveCachedArguments(beanName);
						}
					}
				}
				if (this. == null) {
					if (this. != null && pvs instanceof MutablePropertyValues) {
					}
					this. = .;
				}
				if (arguments != null) {
					ReflectionUtils.makeAccessible(method);
					method.invoke(beanarguments);
				}
			}
				throw ex.getTargetException();
			}
			catch (Throwable ex) {
				throw new BeanCreationException("Could not autowire method: " + methodex);
			}
		}
		private Object[] resolveCachedArguments(String beanName) {
			if (this. == null) {
				return null;
			}
			Object[] arguments = new Object[this..length];
			for (int i = 0; i < arguments.lengthi++) {
				arguments[i] = resolvedCachedArgument(beanNamethis.[i]);
			}
			return arguments;
		}
	}
New to GrepCode? Check out our FAQ X