001/*
002 * Copyright 2002-2019 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 org.springframework.beans.factory.support.GenericBeanDefinition;
020import org.springframework.core.type.AnnotationMetadata;
021import org.springframework.core.type.MethodMetadata;
022import org.springframework.core.type.StandardAnnotationMetadata;
023import org.springframework.lang.Nullable;
024import org.springframework.util.Assert;
025
026/**
027 * Extension of the {@link org.springframework.beans.factory.support.GenericBeanDefinition}
028 * class, adding support for annotation metadata exposed through the
029 * {@link AnnotatedBeanDefinition} interface.
030 *
031 * <p>This GenericBeanDefinition variant is mainly useful for testing code that expects
032 * to operate on an AnnotatedBeanDefinition, for example strategy implementations
033 * in Spring's component scanning support (where the default definition class is
034 * {@link org.springframework.context.annotation.ScannedGenericBeanDefinition},
035 * which also implements the AnnotatedBeanDefinition interface).
036 *
037 * @author Juergen Hoeller
038 * @author Chris Beams
039 * @since 2.5
040 * @see AnnotatedBeanDefinition#getMetadata()
041 * @see org.springframework.core.type.StandardAnnotationMetadata
042 */
043@SuppressWarnings("serial")
044public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
045
046        private final AnnotationMetadata metadata;
047
048        @Nullable
049        private MethodMetadata factoryMethodMetadata;
050
051
052        /**
053         * Create a new AnnotatedGenericBeanDefinition for the given bean class.
054         * @param beanClass the loaded bean class
055         */
056        public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
057                setBeanClass(beanClass);
058                this.metadata = AnnotationMetadata.introspect(beanClass);
059        }
060
061        /**
062         * Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
063         * allowing for ASM-based processing and avoidance of early loading of the bean class.
064         * Note that this constructor is functionally equivalent to
065         * {@link org.springframework.context.annotation.ScannedGenericBeanDefinition
066         * ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a
067         * bean was discovered specifically via component-scanning as opposed to other means.
068         * @param metadata the annotation metadata for the bean class in question
069         * @since 3.1.1
070         */
071        public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
072                Assert.notNull(metadata, "AnnotationMetadata must not be null");
073                if (metadata instanceof StandardAnnotationMetadata) {
074                        setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
075                }
076                else {
077                        setBeanClassName(metadata.getClassName());
078                }
079                this.metadata = metadata;
080        }
081
082        /**
083         * Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
084         * based on an annotated class and a factory method on that class.
085         * @param metadata the annotation metadata for the bean class in question
086         * @param factoryMethodMetadata metadata for the selected factory method
087         * @since 4.1.1
088         */
089        public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) {
090                this(metadata);
091                Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null");
092                setFactoryMethodName(factoryMethodMetadata.getMethodName());
093                this.factoryMethodMetadata = factoryMethodMetadata;
094        }
095
096
097        @Override
098        public final AnnotationMetadata getMetadata() {
099                return this.metadata;
100        }
101
102        @Override
103        @Nullable
104        public final MethodMetadata getFactoryMethodMetadata() {
105                return this.factoryMethodMetadata;
106        }
107
108}