001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.beans.factory.annotation;
018
019import java.lang.annotation.Annotation;
020import java.util.Set;
021
022import org.springframework.beans.BeansException;
023import org.springframework.beans.factory.BeanClassLoaderAware;
024import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
025import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
026import org.springframework.beans.factory.support.DefaultListableBeanFactory;
027import org.springframework.core.Ordered;
028import org.springframework.lang.Nullable;
029import org.springframework.util.ClassUtils;
030
031/**
032 * A {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor}
033 * implementation that allows for convenient registration of custom autowire
034 * qualifier types.
035 *
036 * <pre class="code">
037 * &lt;bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"&gt;
038 *   &lt;property name="customQualifierTypes"&gt;
039 *     &lt;set&gt;
040 *       &lt;value&gt;mypackage.MyQualifier&lt;/value&gt;
041 *     &lt;/set&gt;
042 *   &lt;/property&gt;
043 * &lt;/bean&gt;</pre>
044 *
045 * @author Mark Fisher
046 * @author Juergen Hoeller
047 * @since 2.5
048 * @see org.springframework.beans.factory.annotation.Qualifier
049 */
050public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanClassLoaderAware, Ordered {
051
052        private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered
053
054        @Nullable
055        private Set<?> customQualifierTypes;
056
057        @Nullable
058        private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
059
060
061        public void setOrder(int order) {
062                this.order = order;
063        }
064
065        @Override
066        public int getOrder() {
067                return this.order;
068        }
069
070        @Override
071        public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
072                this.beanClassLoader = beanClassLoader;
073        }
074
075        /**
076         * Register custom qualifier annotation types to be considered
077         * when autowiring beans. Each element of the provided set may
078         * be either a Class instance or a String representation of the
079         * fully-qualified class name of the custom annotation.
080         * <p>Note that any annotation that is itself annotated with Spring's
081         * {@link org.springframework.beans.factory.annotation.Qualifier}
082         * does not require explicit registration.
083         * @param customQualifierTypes the custom types to register
084         */
085        public void setCustomQualifierTypes(Set<?> customQualifierTypes) {
086                this.customQualifierTypes = customQualifierTypes;
087        }
088
089
090        @Override
091        @SuppressWarnings("unchecked")
092        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
093                if (this.customQualifierTypes != null) {
094                        if (!(beanFactory instanceof DefaultListableBeanFactory)) {
095                                throw new IllegalStateException(
096                                                "CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
097                        }
098                        DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
099                        if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
100                                dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
101                        }
102                        QualifierAnnotationAutowireCandidateResolver resolver =
103                                        (QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver();
104                        for (Object value : this.customQualifierTypes) {
105                                Class<? extends Annotation> customType = null;
106                                if (value instanceof Class) {
107                                        customType = (Class<? extends Annotation>) value;
108                                }
109                                else if (value instanceof String) {
110                                        String className = (String) value;
111                                        customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
112                                }
113                                else {
114                                        throw new IllegalArgumentException(
115                                                        "Invalid value [" + value + "] for custom qualifier type: needs to be Class or String.");
116                                }
117                                if (!Annotation.class.isAssignableFrom(customType)) {
118                                        throw new IllegalArgumentException(
119                                                        "Qualifier type [" + customType.getName() + "] needs to be annotation type");
120                                }
121                                resolver.addQualifierType(customType);
122                        }
123                }
124        }
125
126}