spring源码阅读——GenericBeanDefinition及其子类

目录

继承图

源码

     GenericBeanDefinition

     AnnotatedGenericBeanDefinition

     ScannedGenericBeanDefinition


本文难免有错误,如有错误,欢迎指出

继承图

AnnotatedGenericBeanDefinition:存储@Configuration注解注释的类

ScannedGenericBeanDefinition:存储@Component、@Service、@Controller等注解注释的类

spring初始化时,会用GenericBeanDefinition或是ConfigurationClassBeanDefinition(用@Bean注解注释的类)存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition

源码

GenericBeanDefinition

这里省去构造函数:

/**
 * GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
 * Like any bean definition, it allows for specifying a class plus optionally
 * constructor argument values and property values. Additionally, deriving from a
 * parent bean definition can be flexibly configured through the "parentName" property.
 *
 * <p>In general, use this {@code GenericBeanDefinition} class for the purpose of
 * registering user-visible bean definitions (which a post-processor might operate on,
 * potentially even reconfiguring the parent name). Use {@code RootBeanDefinition} /
 * {@code ChildBeanDefinition} where parent/child relationships happen to be pre-determined.
 *
 * @author Juergen Hoeller
 * @since 2.5
 * @see #setParentName
 * @see RootBeanDefinition
 * @see ChildBeanDefinition
 */
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {

	@Nullable
	private String parentName;


    	@Override
	public void setParentName(@Nullable String parentName) {
		this.parentName = parentName;
	}

	@Override
	@Nullable
	public String getParentName() {
		return this.parentName;
	}
}

GenericBeanDefinition的patentName属性指定了当前类的父类,最重要的是它实现了parentName属性的setter、getter函数,RootBeanDefinition没有parentName属性,对应的getter函数只是返回null,setter函数不提供赋值操作

也就是说RootBeanDefinition不提供继承相关的操作,但是初始化时使用的是RootBeanDefinition,那父类的性质如何体现?

这里要注意一点,子类会覆盖父类中相同的属性,所以Spring会首先初始化父类的RootBeanDefinition,然后根据子类的GenericBeanDefinition覆盖父类中相应的属性,最终获得子类的RootBeanDefinition,这个比较巧妙,不需要使用两个对象来体现父类与子类的关系,以后自己写代码时可以借鉴一下

AnnotatedGenericBeanDefinition

@SuppressWarnings("serial")
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
        通过这个接口,可以得知类含有的注释
	private final AnnotationMetadata metadata;

        存储工厂方法的元数据,这个接口的具体操作请看下文
	@Nullable
	private MethodMetadata factoryMethodMetadata;

        @Override
	public final AnnotationMetadata getMetadata() {
		return this.metadata;
	}

	@Override
	@Nullable
	public final MethodMetadata getFactoryMethodMetadata() {
		return this.factoryMethodMetadata;
	}

}

AnnotatedBeanDefinition定义了getMetadata与getFactoryMethodMetadata方法,这里有两个特殊的属性:AnnotationMetadata与MethodMetadata,这两个接口源码如下:

AnnotationMetadata:

/**
 * Interface that defines abstract access to the annotations of a specific
 * class, in a form that does not require that class to be loaded yet.
 *
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Phillip Webb
 * @author Sam Brannen
 * @since 2.5
 * @see StandardAnnotationMetadata
 * @see org.springframework.core.type.classreading.MetadataReader#getAnnotationMetadata()
 * @see AnnotatedTypeMetadata
 */

元注解:相当于父类,某些注解是在元注解的基础上扩展出来的,典型的元注解是@Component,@Service、@Controller扩展了@Component注解 
 
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {

	/**
	 * Get the fully qualified class names of all annotation types that
	 * are <em>present</em> on the underlying class.
	 * @return the annotation type names
	 */
	 返回注解的类全限定名
	Set<String> getAnnotationTypes();

	/**
	 * Get the fully qualified class names of all meta-annotation types that
	 * are <em>present</em> on the given annotation type on the underlying class.
	 * @param annotationName the fully qualified class name of the meta-annotation
	 * type to look for
	 * @return the meta-annotation type names, or an empty set if none found
	 */
	 获得annottationName对应的元注解的类全限定名
	Set<String> getMetaAnnotationTypes(String annotationName);

	/**
	 * Determine whether an annotation of the given type is <em>present</em> on
	 * the underlying class.
	 * @param annotationName the fully qualified class name of the annotation
	 * type to look for
	 * @return {@code true} if a matching annotation is present
	 */
	确定是否含有某个注解
	boolean hasAnnotation(String annotationName);

	/**
	 * Determine whether the underlying class has an annotation that is itself
	 * annotated with the meta-annotation of the given type.
	 * @param metaAnnotationName the fully qualified class name of the
	 * meta-annotation type to look for
	 * @return {@code true} if a matching meta-annotation is present
	 */
	确定是否含有某个元注解
	boolean hasMetaAnnotation(String metaAnnotationName);

	/**
	 * Determine whether the underlying class has any methods that are
	 * annotated (or meta-annotated) with the given annotation type.
	 * @param annotationName the fully qualified class name of the annotation
	 * type to look for
	 */
	确定类的方法是否含有某个注解
	boolean hasAnnotatedMethods(String annotationName);

	/**
	 * Retrieve the method metadata for all methods that are annotated
	 * (or meta-annotated) with the given annotation type.
	 * <p>For any returned method, {@link MethodMetadata#isAnnotated} will
	 * return {@code true} for the given annotation type.
	 * @param annotationName the fully qualified class name of the annotation
	 * type to look for
	 * @return a set of {@link MethodMetadata} for methods that have a matching
	 * annotation. The return value will be an empty set if no methods match
	 * the annotation type.
	 */
	 返回类中所有被注解注释的方法
	Set<MethodMetadata> getAnnotatedMethods(String annotationName);

}

MethodMetadata:

/**
 * Interface that defines abstract access to the annotations of a specific
 * class, in a form that does not require that class to be loaded yet.
 *
 * @author Juergen Hoeller
 * @author Mark Pollack
 * @author Chris Beams
 * @author Phillip Webb
 * @since 3.0
 * @see StandardMethodMetadata
 * @see AnnotationMetadata#getAnnotatedMethods
 * @see AnnotatedTypeMetadata
 */
public interface MethodMetadata extends AnnotatedTypeMetadata {

	/**
	 * Return the name of the method.
	 */
	返回方法的名字
	String getMethodName();

	/**
	 * Return the fully-qualified name of the class that declares this method.
	 */
	返回该方法所属的类的全限定名
	String getDeclaringClassName();

	/**
	 * Return the fully-qualified name of this method's declared return type.
	 * @since 4.2
	 */
	返回该方法返回类型的全限定名
	String getReturnTypeName();

	
	以下接口判断方法是不是抽象、静态、final、override
	/**
	 * Return whether the underlying method is effectively abstract:
	 * i.e. marked as abstract on a class or declared as a regular,
	 * non-default method in an interface.
	 * @since 4.2
	 */
	boolean isAbstract();

	/**
	 * Return whether the underlying method is declared as 'static'.
	 */
	boolean isStatic();

	/**
	 * Return whether the underlying method is marked as 'final'.
	 */
	boolean isFinal();

	/**
	 * Return whether the underlying method is overridable,
	 * i.e. not marked as static, final or private.
	 */
	boolean isOverridable();

}	

AnnotationGenericBeanDefinition在GenenricBeanDefinition的基础上提供了访问注解、工厂方法的机制

ScannedGenericBeanDefinition

这个类和AnnotatedGenericBeanDefinition差不多,就不在过多解释 

public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {

	private final AnnotationMetadata metadata;


	/**
	 * Create a new ScannedGenericBeanDefinition for the class that the
	 * given MetadataReader describes.
	 * @param metadataReader the MetadataReader for the scanned target class
	 */
	public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
		Assert.notNull(metadataReader, "MetadataReader must not be null");
		this.metadata = metadataReader.getAnnotationMetadata();
		setBeanClassName(this.metadata.getClassName());
	}


	@Override
	public final AnnotationMetadata getMetadata() {
		return this.metadata;
	}

	@Override
	@Nullable
	public MethodMetadata getFactoryMethodMetadata() {
		return null;
	}

}

猜你喜欢

转载自blog.csdn.net/dhaiuda/article/details/83311495
今日推荐