前面分析SpringIOC的过程中,大量提到了一个东西-BeanDefinition,中文翻译就是Bean定义,什么叫做Bean定义呢,类比对一个人的定义,就是一个人的名字,身高,体重,国籍,身份证号等,这些属性就可以描述一个具体的人。
在Spring中,虽然都是叫做bean,但是定义Bean的方式却有很多,比如,使用xml文件配置bean,使用@Configuration配置Bean,使用@Bean注解,等等,不同的Bean还有着不同的依赖,如何来定义这些不同的Bean呢,Spring提供了BeanDefinition.
今天我们就来看看BeanDefinition在Spring解析配置文件中怎么创造出来的又是如何注册的。

BeanDefinition接口继承了AtrributeAccessor和BeanMetadataElement.
来简单看下这两个接口的作用,
public interface AttributeAccessor {
	
	void setAttribute(String name, @Nullable Object value);
	
	@Nullable
	Object getAttribute(String name);
	@Nullable
	Object removeAttribute(String name);
	
	boolean hasAttribute(String name);
	
	String[] attributeNames();
}
定义了或者任意对象的附加属性的操作。
public interface BeanMetadataElement {
	/**
	 * Return the configuration source {@code Object} for this metadata element
	 * (may be {@code null}).
	 */
	@Nullable
	Object getSource();
}
BeanDefinition元数据,返回该Bean的来源
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
   // 默认只提供 sington 和 prototype 两种,
   
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
   int ROLE_APPLICATION = 0;
   int ROLE_SUPPORT = 1;
   int ROLE_INFRASTRUCTURE = 2;
   // 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。
   void setParentName(String parentName);
   // 获取父 Bean
   String getParentName();
   // 设置 Bean 的类名称,将来是要通过反射来生成实例的
   void setBeanClassName(String beanClassName);
   // 获取 Bean 的类名称
   String getBeanClassName();
   // 设置 bean 的 scope
   void setScope(String scope);
   String getScope();
   // 设置是否懒加载
   void setLazyInit(boolean lazyInit);
   boolean isLazyInit();
   // 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
   // 是 depends-on="" 属性设置的值。
   void setDependsOn(String... dependsOn);
   // 返回该 Bean 的所有依赖
   String[] getDependsOn();
   // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
   // 如果根据名称注入,即使这边设置了 false,也是可以的
   void setAutowireCandidate(boolean autowireCandidate);
   // 该 Bean 是否可以注入到其他 Bean 中
   boolean isAutowireCandidate();
   // 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
   void setPrimary(boolean primary);
   // 是否是 primary 的
   boolean isPrimary();
   // 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
   // 一句话就是:有些实例不是用反射生成的,而是用工厂模式生成的
   void setFactoryBeanName(String factoryBeanName);
   // 获取工厂名称
   String getFactoryBeanName();
   // 指定工厂类中的 工厂方法名称
   void setFactoryMethodName(String factoryMethodName);
   // 获取工厂类中的 工厂方法名称
   String getFactoryMethodName();
   // 构造器参数
   ConstructorArgumentValues getConstructorArgumentValues();
   // Bean 中的属性值,后面给 bean 注入属性值的时候会说到
   MutablePropertyValues getPropertyValues();
   // 是否 singleton
   boolean isSingleton();
   // 是否 prototype
   boolean isPrototype();
   // 如果这个 Bean 是被设置为 abstract,那么不能实例化,
   // 常用于作为 父bean 用于继承,其实也很少用......
   boolean isAbstract();
   int getRole();
   String getDescription();
   String getResourceDescription();
   BeanDefinition getOriginatingBeanDefinition();
}
上面看到的BeanDefinition只是一个接口,它下面有几个实现类。

AbstractBeanDefinition
抽象类统一实现了BeanDefinition定义的一部分操作
RootBeanDefinition
根据xml,JavaConfig配置的Bean
ChildBeanDefinition
可以让子BeanDefinition定义拥有从父母哪里继承配置的能力
GenericBeanDefinition
可以动态设置父bean
除此之外,BeanDefinition还有一个扩展的接口AnnotatedBeanDefinition,表示使用注解配置的Bean
这个接口有两个重要的属性,AnnotationMetadata,MethodMetadata分别表示BeanDefinition的注解元信息和方法元信息 实现了此接口的BeanDefinition可以获取到注解元数据和方法元数据
原文:https://www.cnblogs.com/watertreestar/p/12830261.html