浅读 Spring BeanDefinition

256 阅读3分钟

BeanDefinition 是什么

Spring的面试题经常会问到spring的生命周期,其中就包含了解析,验证....在解析的时候就是将扫描的类封装成BeanDefinition,所以BeanDefinition可以认为是对类的描述,类的定义。

BeanDefinition


public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
	// 单例的字符串
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; 
    //原型的字符串
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
	// 设置父 BeanDifition的名字
	@Nullable
	String getParentName();
	// 设置 bean 的clsss名称
	void setBeanClassName(@Nullable String beanClassName);
	@Nullable
	String getBeanClassName();
	//设置 scope 是原型还是单例
	void setScope(@Nullable String scope);
	String getScope();
   //设置是否懒加载
	void setLazyInit(boolean lazyInit);
	boolean isLazyInit();
    // 设置 要先加载的类
	void setDependsOn(@Nullable String... dependsOn);
	String[] getDependsOn();
    //设置自动配置的候选,也就是如果用自动配置是通过类型,如果有两个相同的类型
    //需要有优先级,如果设置 true 就是优先这个类被注入 可以通过注解
	void setAutowireCandidate(boolean autowireCandidate);
	boolean isAutowireCandidate();
    //跟 AutowireCandidate 有点类型 可以设置优先级 可以通过@Primary
	void setPrimary(boolean primary);
	boolean isPrimary();
    //设置工厂名称 todo 不知道
	void setFactoryBeanName(@Nullable String factoryBeanName);
	String getFactoryBeanName();
    //设置工厂方法名称 挺重要的,平时使用的 @Bean 就是将方法加载成 factoryMethodName
    //如果是 @Bean 那么 beanClass 为null
	void setFactoryMethodName(@Nullable String factoryMethodName);
	@Nullable
	String getFactoryMethodName();
    //设置构造方法入参
	ConstructorArgumentValues getConstructorArgumentValues();
	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}
    //设置对象属性以及属性的值
	MutablePropertyValues getPropertyValues();
	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}
   //初始化方法名称
	void setInitMethodName(@Nullable String initMethodName);
	@Nullable
	String getInitMethodName();
    //设置销毁方法名称
	void setDestroyMethodName(@Nullable String destroyMethodName);
	String getDestroyMethodName();
    //设置角色 todo
	void setRole(int role);
	int getRole();
	void setDescription(@Nullable String description);
	String getDescription();
    //是否是单例
	boolean isSingleton();
    //是否是原型
	boolean isPrototype();
    //是否是抽象,这个并不是抽象类的意思,而是这个BeanDefition是否可以被继承,当作模板 
	boolean isAbstract();
	String getResourceDescription();
	BeanDefinition getOriginatingBeanDefinition();
}

图解 BeanDefinition 家族

  • 1.通过上图可知 BeanDefinition 算是最顶层的,下面的实现类有AnnotatedBeanDefinition``ChildBeanDefinition``GenericBeanDefinition``RootBeanDefinition,这四个的下面又有实现类ScannedGenericBeanDefinition``AnnotatedGenericBeanDefinition
  • 2.BeanDefinition 继承了 AttributeAccessor, BeanMetadataElement
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

}
  • 3.BeanMetadataAttributeAccessorAttributeAccessor, BeanMetadataElement的具体实现,作用是什么?BeanMetadataElement顾名思义,bean的元数据,里面有个抽象方法Object getSource()就是获得bean的元数据,也就是这个类所在磁盘的文件位置。AttributeAccessor一看就感觉跟参数有关,抽象方法有setAttribute``getAttribute等等,也就是对参数的增删改查,这个参数可以存放一些类的属性等等。

  • 4.RootBeanDefinitionChildBeanDefinition 一看就像父子关系,RootBeanDefinition可以作为ChildBeanDefinition的模板,ChildBeanDefinition 在实例化的时候就会强制传 parentName,这样ChildBeanDefinition就会继承RootBeanDefinition一些属性。

  • 5.GenericBeanDefinition是一个全能通用的类,既可以当模板,也可以去继承模板

  • 6.AnnotatedGenericBeanDefinition是配置类的bean定义,比如@Configuration 注解类,但是并不是所有注有@Configuration 都是 AnnotatedGenericBeanDefinition ,如果注有 @Configuration的类,然后被spring通过扫描出来的就是ScannedGenericBeanDefinition,一般来说,在springboot就是启动类跟Spring.factories是AnnotatedGenericBeanDefinition ,其他类基本都是被扫描出来的。

  • 7.ScannedGenericBeanDefinition是被扫描出来的bean定义,比如注解 @Comonent 注解被扫描出来