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}