View Javadoc
1   /*
2    * Copyright 2002-2012 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.beans.factory.annotation;
18  
19  import java.lang.annotation.Annotation;
20  import java.util.Set;
21  
22  import org.springframework.beans.BeansException;
23  import org.springframework.beans.factory.BeanClassLoaderAware;
24  import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
25  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
26  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
27  import org.springframework.core.Ordered;
28  import org.springframework.util.ClassUtils;
29  
30  /**
31   * A {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor}
32   * implementation that allows for convenient registration of custom autowire
33   * qualifier types.
34   *
35   * <pre class="code">
36   * &lt;bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"&gt;
37   *   &lt;property name="customQualifierTypes"&gt;
38   *     &lt;set&gt;
39   *       &lt;value&gt;mypackage.MyQualifier&lt;/value&gt;
40   *     &lt;/set&gt;
41   *   &lt;/property&gt;
42   * &lt;/bean&gt;</pre>
43   *
44   * @author Mark Fisher
45   * @author Juergen Hoeller
46   * @since 2.5
47   * @see org.springframework.beans.factory.annotation.Qualifier
48   */
49  public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanClassLoaderAware, Ordered {
50  
51  	private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered
52  
53  	private Set<?> customQualifierTypes;
54  
55  	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
56  
57  
58  	public void setOrder(int order) {
59  		this.order = order;
60  	}
61  
62  	@Override
63  	public int getOrder() {
64  		return this.order;
65  	}
66  
67  	@Override
68  	public void setBeanClassLoader(ClassLoader beanClassLoader) {
69  		this.beanClassLoader = beanClassLoader;
70  	}
71  
72  	/**
73  	 * Register custom qualifier annotation types to be considered
74  	 * when autowiring beans. Each element of the provided set may
75  	 * be either a Class instance or a String representation of the
76  	 * fully-qualified class name of the custom annotation.
77  	 * <p>Note that any annotation that is itself annotated with Spring's
78  	 * {@link org.springframework.beans.factory.annotation.Qualifier}
79  	 * does not require explicit registration.
80  	 * @param customQualifierTypes the custom types to register
81  	 */
82  	public void setCustomQualifierTypes(Set<?> customQualifierTypes) {
83  		this.customQualifierTypes = customQualifierTypes;
84  	}
85  
86  
87  	@Override
88  	@SuppressWarnings("unchecked")
89  	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
90  		if (this.customQualifierTypes != null) {
91  			if (!(beanFactory instanceof DefaultListableBeanFactory)) {
92  				throw new IllegalStateException(
93  						"CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
94  			}
95  			DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
96  			if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
97  				dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
98  			}
99  			QualifierAnnotationAutowireCandidateResolver resolver =
100 					(QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver();
101 			for (Object value : this.customQualifierTypes) {
102 				Class<? extends Annotation> customType = null;
103 				if (value instanceof Class) {
104 					customType = (Class<? extends Annotation>) value;
105 				}
106 				else if (value instanceof String) {
107 					String className = (String) value;
108 					customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
109 				}
110 				else {
111 					throw new IllegalArgumentException(
112 							"Invalid value [" + value + "] for custom qualifier type: needs to be Class or String.");
113 				}
114 				if (!Annotation.class.isAssignableFrom(customType)) {
115 					throw new IllegalArgumentException(
116 							"Qualifier type [" + customType.getName() + "] needs to be annotation type");
117 				}
118 				resolver.addQualifierType(customType);
119 			}
120 		}
121 	}
122 
123 }