介绍
在SpringIOC流程分析过程中,对于Bean的控制反转创建过程一定离不开BeanDefinition.虽然它是接口,基于它有
AbstractBeanDefinition
,RootBeanDefinition
,GenericBeanDefinition
等各种实现.创建Bean的过程也会将不同的BeanDefinition转成RootBeanDefinition来进行使用.
它经过Spring解析对应类或配置保存了该Bean的各种信息,例如该Bean的类型、是否是抽象类、作用域、该Bean的初始化,销毁方法、需要注入那些Bean等.
可以理解为存放Bean创建所需的材料列表.然后Spring根据创建说明来进行Bean的创建操作
创建说明包含材料获取以及生成.BeanDefinitionRegistry
负责BeanDefinition注册即材料获取环节,BeanFactory
负责Bean的创建环节,管控Bean的部分生命周期.最后交由Spring容器调度
例外
通过beanFactory.registerSingleton方法手动加入Bean是不会用到BeanDefinition的,这里是将现有Bean加入BeanFactory中.
例如:bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
BeanDefinition接口
/** * 该接口主要定义一些基础Bean元数据信息属性值以及基础属性获取方法 */ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // 定义单例/多例的常量值 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; // 定义Bean的作用角色. // 0表示应用级.1表示配置拓展支撑级.2表示内部构造级。0,1为自定义级别 int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // 下面是可修改的定义属性 // 指定父类 void setParentName(@Nullable String parentName); @Nullable String getParentName(); // 当前类 void setBeanClassName(@Nullable String beanClassName); @Nullable String getBeanClassName(); // 指定作用域.SCOPE_SINGLETON或者SCOPE_PROTOTYPE两种 void setScope(@Nullable String scope); @Nullable String getScope(); // 指定是否懒加载 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 指定依赖对象列表 void setDependsOn(@Nullable String... dependsOn); @Nullable String[] getDependsOn(); // 是否支持自动注入.支持的才可以被注入到其他地方.只支持@Autorire方式判断 void setAutowireCandidate(boolean autowireCandidate); boolean isAutowireCandidate(); // 当多Bean类型重复是否是注入Bean的首选 void setPrimary(boolean primary); boolean isPrimary(); // 设置该Bean的工厂Bean(专门创建该Bean的工厂). void setFactoryBeanName(@Nullable String factoryBeanName); @Nullable String getFactoryBeanName(); // 设置工厂方法. void setFactoryMethodName(@Nullable String factoryMethodName); @Nullable String getFactoryMethodName(); ConstructorArgumentValues getConstructorArgumentValues(); default boolean hasConstructorArgumentValues() { return !getConstructorArgumentValues().isEmpty(); } // 该Bean的属性集合 MutablePropertyValues getPropertyValues(); default boolean hasPropertyValues() { return !getPropertyValues().isEmpty(); } // 初始化执行方法. @PostConstruct注解标注的/配置文件指定的. void setInitMethodName(@Nullable String initMethodName); @Nullable String getInitMethodName(); // 销毁执行方法 @PreDestroy注解标注的/配置文件指定的. // 也可以@Bean(initMethod = "init",destroyMethod = "destory")指定 void setDestroyMethodName(@Nullable String destroyMethodName); @Nullable String getDestroyMethodName(); // 设置该Bean角色 void setRole(int role); int getRole(); // void setDescription(@Nullable String description); @Nullable String getDescription(); // Read-only attributes // 返回该类解析过后的元信息 ResolvableType getResolvableType(); // 是否是单例 boolean isSingleton(); // 是否是多例 boolean isPrototype(); // 是否是抽象类 boolean isAbstract(); @Nullable String getResourceDescription(); // 返回最原始BeanDefinition.当该Bean有被其他postProcessor处理过(代理修饰).则该方法可以返回最原先的BeanDefinition @Nullable BeanDefinition getOriginatingBeanDefinition(); }
子接口AnnotatedBeanDefinition定义访问目标类注解信息接口
// 该类意思是无需加载目标类即可获取目标类的信息 public interface AnnotatedBeanDefinition extends BeanDefinition { // 获取类上的注解信息 AnnotationMetadata getMetadata(); // 如果该Bean定义了工厂方法,则返回工厂方法元数据信息 // 名字、返回类型、是否抽象、是否是静态的、是否不可继承、是否可重写 @Nullable MethodMetadata getFactoryMethodMetadata(); }
AbstractBeanDefinition定义了Bean创建默认配置
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { //默认的SCOPE,默认是单例 public static final String SCOPE_DEFAULT = ""; // 自动装配常量类型定义: 是否自动装配、根据名称/类型/构造器装配 public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; //检查依赖是否合法,在本类中,默认不进行依赖检查 public static final int DEPENDENCY_CHECK_NONE = 0; // 不进行检查 public static final int DEPENDENCY_CHECK_OBJECTS = 1; //如果依赖类型为对象引用,则需要检查 public static final int DEPENDENCY_CHECK_SIMPLE = 2; //对简单属性的依赖进行检查 public static final int DEPENDENCY_CHECK_ALL = 3; //对所有属性的依赖进行检查 //若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字,目前来说,推断的销毁方法的名字一般为close或是shutdown //(即未指定Bean的销毁方法,但是内部定义了名为close或是shutdown的方法,则容器推断其为销毁方法) public static final String INFER_METHOD = "(inferred)"; //定义一些SpringIOC的默认属性信息 //Bean的class对象或是类的全限定名 @Nullable private volatile Object beanClass; //默认的scope是单例 @Nullable private String scope = SCOPE_DEFAULT; //默认不为抽象类 private boolean abstractFlag = false; //默认不懒加载 private boolean lazyInit = false; //默认是没有依赖注入的模式 private int autowireMode = AUTOWIRE_NO; //默认不进行依赖检查 private int dependencyCheck = DEPENDENCY_CHECK_NONE; // @@DependsOn 默认没有依赖 @Nullable private String[] dependsOn; // 是否支持自动装配 // false时,容器在查找自动装配对象时,将不考虑该bean private boolean autowireCandidate = true; // 默认不是首选的 private boolean primary = false; //存储该Bean依赖中使用@Qualifier标注的自动装配信息,多指定依赖的Bean名称.防止多个同类型Bean造成的NoUniqueBeanDefinitionException异常 private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(0); //我理解为通过这个函数的逻辑初始化Bean,而不是构造函数或是工厂方法(相当于自己去实例化,而不是交给Bean工厂) @Nullable private Supplier<?> instanceSupplier; //是否允许访问非public方法和属性,应用于构造函数、工厂方法、init、destroy方法的解析 默认是true,表示啥都可以访问 private boolean nonPublicAccessAllowed = true; // 是否以一种宽松的模式解析构造函数,默认为true(宽松和严格体现在类型匹配上) private boolean lenientConstructorResolution = true; //工厂类名(注意是String类型,不是Class类型) 对应bean属性factory-method @Nullable private String factoryBeanName; //工厂方法名(注意是String类型,不是Method类型) @Nullable private String factoryMethodName; //记录构造函数注入属性,对应bean属性constructor-arg @Nullable private ConstructorArgumentValues constructorArgumentValues; //Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖 @Nullable private MutablePropertyValues propertyValues; //方法重写的持有者,记录lookup-method、replaced-method元素 @Lookup等 @Nullable private MethodOverrides methodOverrides; //init函数的名字 @Nullable private String initMethodName; //destory函数的名字 @Nullable private String destroyMethodName; //是否执行init-method,程序设置 private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; //是否是合成类(是不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类) //创建AOP时候为true private boolean synthetic = false; //Bean的角色,为用户自定义Bean private int role = BeanDefinition.ROLE_APPLICATION; // Bean的描述信息 @Nullable private String description; //the resource that this bean definition came from // 类的源信息(加载一个类可能是一个文件/网络地址) @Nullable private Resource resource; // 其实就是给reource赋值了,使用了BeanDefinitionResource public void setOriginatingBeanDefinition(BeanDefinition originatingBd) { this.resource = new BeanDefinitionResource(originatingBd); } // 上面有赋值,所以get的时候就是返回上面set进来的值 public BeanDefinition getOriginatingBeanDefinition() { return (this.resource instanceof BeanDefinitionResource ? ((BeanDefinitionResource) this.resource).getBeanDefinition() : null); } //克隆Bean的定义信息 @Override public Object clone() { return cloneBeanDefinition(); } public abstract AbstractBeanDefinition cloneBeanDefinition(); }
RootBeanDefinition
生成Bean时会将不同的BeanDefinition合并成RootBeanDefinition.当某个类有父类会将父类的BeanDefinition合并进该类的BeanDefinition中.在AbstractBeanFactory.doGetBean方法中,也是Context.refresh的第十一步执行
public class RootBeanDefinition extends AbstractBeanDefinition { //BeanDefinitionHolder存储有Bean的名称、别名、BeanDefinition @Nullable private BeanDefinitionHolder decoratedDefinition; // AnnotatedElement 是java反射包的接口,通过它可以查看Bean的注解信息 @Nullable private AnnotatedElement qualifiedElement; //允许缓存 boolean allowCaching = true; //从字面上理解:工厂方法是否唯一 boolean isFactoryMethodUnique = false; //封装了java.lang.reflect.Type,提供了泛型相关的操作,具体请查看: // ResolvableType 可以专题去了解一下子,虽然比较简单 但常见 @Nullable volatile ResolvableType targetType; //缓存class,表明RootBeanDefinition存储哪个类的信息 @Nullable volatile Class<?> resolvedTargetType; //缓存工厂方法的返回类型 @Nullable volatile ResolvableType factoryMethodReturnType; /** Common lock for the four constructor fields below */ final Object constructorArgumentLock = new Object(); //缓存已经解析的构造函数或是工厂方法,Executable是Method、Constructor类型的父类 @Nullable Executable resolvedConstructorOrFactoryMethod; //表明构造函数参数是否解析完毕 boolean constructorArgumentsResolved = false; //缓存完全解析的构造函数参数 @Nullable Object[] resolvedConstructorArguments; //缓存待解析的构造函数参数,即还没有找到对应的实例,可以理解为还没有注入依赖的形参 @Nullable Object[] preparedConstructorArguments; /** Common lock for the two post-processing fields below */ final Object postProcessingLock = new Object(); //表明是否被MergedBeanDefinitionPostProcessor处理过 boolean postProcessed = false; //在生成代理的时候会使用,表明是否已经生成代理 @Nullable volatile Boolean beforeInstantiationResolved; //实际缓存的类型是Constructor、Field、Method类型 @Nullable private Set<Member> externallyManagedConfigMembers; //InitializingBean中的init回调函数名——afterPropertiesSet会在这里记录,以便进行生命周期回调 @Nullable private Set<String> externallyManagedInitMethods; //DisposableBean的destroy回调函数名——destroy会在这里记录,以便进行生命周期回调 @Nullable private Set<String> externallyManagedDestroyMethods; }
AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition只能用于已经被注册或被扫描到的类
public static void main(String[] args) { AnnotatedBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(RootConfig.class); // 获取注解方式便捷 Set<String> annotationTypes = beanDefinition.getMetadata().getAnnotationTypes(); System.out.println(annotationTypes); //[org.springframework.context.annotation.ComponentScan, org.springframework.context.annotation.Configuration] System.out.println(beanDefinition.isSingleton()); //true System.out.println(beanDefinition.getBeanClassName()); //com.config.RootConfig }
ConfigurationClassBeanDefinition
是ConfigurationClassBeanDefinitionReader的一个私有的静态内部类:这个类负责将@Bean注解的方法转换为对应的ConfigurationClassBeanDefinition类(非常的重要),直接继承自RootBeanDefinition
最后
Spring初始化时,会用
GenericBeanDefinition
或是ConfigurationClassBeanDefinition
(用@Bean注解注释的类)存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition