了解SpringIOC流程重要组件BeanDefinition

介绍

在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

参考

Spring IoC容器中核心定义之------BeanDefinition深入分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值