alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (QualifierAnnotationAutowireCandidateResolver.java)

This example Spring Framework source code file (QualifierAnnotationAutowireCandidateResolver.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

abstractbeandefinition, annotation, annotation, autowirecandidateresolver, class, class, hashset, map, object, object, qualifierannotationautowirecandidateresolver, qualifierannotationautowirecandidateresolver, simpletypeconverter, string, util

The Spring Framework QualifierAnnotationAutowireCandidateResolver.java source code

/*
 * Copyright 2002-2007 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.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.AutowireCandidateResolver;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

/**
 * {@link AutowireCandidateResolver} implementation that matches bean definition
 * qualifiers against qualifier annotations on the field or parameter to be autowired.
 *
 * @author Mark Fisher
 * @author Juergen Hoeller
 * @since 2.5
 * @see AutowireCandidateQualifier
 * @see Qualifier
 */
public class QualifierAnnotationAutowireCandidateResolver implements AutowireCandidateResolver {

	private final Set<Class qualifierTypes;


	/**
	 * Create a new QualifierAnnotationAutowireCandidateResolver
	 * for Spring's standard {@link Qualifier} annotation.
	 */
	public QualifierAnnotationAutowireCandidateResolver() {
		this.qualifierTypes = new HashSet<Class(1);
		this.qualifierTypes.add(Qualifier.class);
	}

	/**
	 * Create a new QualifierAnnotationAutowireCandidateResolver
	 * for the given qualifier annotation type.
	 * @param qualifierType the qualifier annotation to look for
	 */
	public QualifierAnnotationAutowireCandidateResolver(Class<? extends Annotation> qualifierType) {
		Assert.notNull(qualifierType, "'qualifierType' must not be null");
		this.qualifierTypes = new HashSet<Class(1);
		this.qualifierTypes.add(qualifierType);
	}

	/**
	 * Create a new QualifierAnnotationAutowireCandidateResolver
	 * for the given qualifier annotation types.
	 * @param qualifierTypes the qualifier annotations to look for
	 */
	public QualifierAnnotationAutowireCandidateResolver(Set<Class qualifierTypes) {
		Assert.notNull(qualifierTypes, "'qualifierTypes' must not be null");
		this.qualifierTypes = new HashSet<Class(qualifierTypes);
	}


	/**
	 * Register the given type to be used as a qualifier when autowiring.
	 * <p>This implementation only supports annotations as qualifier types.
	 * @param qualifierType the annotation type to register
	 */
	public void addQualifierType(Class<? extends Annotation> qualifierType) {
		this.qualifierTypes.add(qualifierType);
	}

	/**
	 * Determine if the provided bean definition is an autowire candidate.
	 * <p>To be considered a candidate the bean's autowire-candidate
	 * attribute must not have been set to 'false'. Also if an annotation on
	 * the field or parameter to be autowired is recognized by this bean factory
	 * as a <em>qualifier, the bean must 'match' against the annotation as
	 * well as any attributes it may contain. The bean definition must contain
	 * the same qualifier or match by meta attributes. A "value" attribute will
	 * fallback to match against the bean name or an alias if a qualifier or
	 * attribute does not match.
	 */
	public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
		if (!bdHolder.getBeanDefinition().isAutowireCandidate()) {
			// if explicitly false, do not proceed with qualifier check
			return false;
		}
		if (descriptor == null || ObjectUtils.isEmpty(descriptor.getAnnotations())) {
			// no qualification necessary
			return true;
		}
		AbstractBeanDefinition bd = (AbstractBeanDefinition) bdHolder.getBeanDefinition();
		SimpleTypeConverter typeConverter = new SimpleTypeConverter();
		Annotation[] annotations = (Annotation[]) descriptor.getAnnotations();
		for (Annotation annotation : annotations) {
			Class<? extends Annotation> type = annotation.annotationType();
			if (isQualifier(type)) {
				AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
				if (qualifier == null) {
					qualifier = bd.getQualifier(ClassUtils.getShortName(type));
				}
				if (qualifier == null && bd.hasBeanClass()) {
					// look for matching annotation on the target class
					Class<?> beanClass = bd.getBeanClass();
					Annotation targetAnnotation = beanClass.getAnnotation(type);
					if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
						return true;
					}
				}
				Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
				if (attributes.isEmpty() && qualifier == null) {
					// if no attributes, the qualifier must be present
					return false;
				}
				for (Map.Entry<String, Object> entry : attributes.entrySet()) {
					String attributeName = entry.getKey();
					Object expectedValue = entry.getValue();
					Object actualValue = null;
					// check qualifier first
					if (qualifier != null) {
						actualValue = qualifier.getAttribute(attributeName);
					}
					if (actualValue == null) {
						// fall back on bean definition attribute
						actualValue = bd.getAttribute(attributeName);
					}
					if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
							(expectedValue.equals(bdHolder.getBeanName()) ||
									ObjectUtils.containsElement(bdHolder.getAliases(), expectedValue))) {
						// fall back on bean name (or alias) match
						continue;
					}
					if (actualValue == null && qualifier != null) {
						// fall back on default, but only if the qualifier is present
						actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
					}
					if (actualValue != null) {
						actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
					}
					if (!expectedValue.equals(actualValue)) {
						return false;
					}
				}
			}
		}
		return true;
	}

	/**
	 * Checks whether the given annotation type is a recognized qualifier type.
	 */
	private boolean isQualifier(Class<? extends Annotation> annotationType) {
		for (Class<? extends Annotation> qualifierType : this.qualifierTypes) {
			if (annotationType.equals(qualifierType) || annotationType.isAnnotationPresent(qualifierType)) {
				return true;
			}
		}
		return false;
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework QualifierAnnotationAutowireCandidateResolver.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.