spring源码分析之BeanDefinition相关

目录

前言:

BeanDefinition的家族系列

1、BeanDefintion的UML类图

2、BeanDefintion家族类详解

2.1、通用接口

2.2、BeanDefintion接口

2.3、AbstractBeanDefintion抽象类

2.4、GenericBeanDefinition类

2.5、 AnnotatedGenericBeanDefinition类

2.6、 ScannedGenericBeanDefinition类

2.7、RootBeanDefinition类

2.8、ChildBeanDefinition类

3、xml配置

         3.1、BeanDefinition的常用属性

3.2、BeanDefinition的继承和注入

3.3、depends-on/init-method/destory-method

3.4、factory-bean/factory-method

3.5、look-up属性

3.6、replace-method属性

  至此BeanDefintion家族相关类以及使用总结完毕。笔者才疏学浅,在本篇博文的分析中如果有理解不到的地方,欢迎大家批评指正。

 

 


前言:

   笔者在一篇关于Spring的BeanFactory的分析的时候数次被BeanDefintion接口弄的云里雾里(有关笔者的Spring源码分析之一BeanFactory相关 感兴趣的可以看看),影响了自己对BeanFactory的阅读。这里趁这次机会好好的捋一捋有关BeanDefinition的家族系列。

一、BeanDefinition的家族系列

   1、BeanDefintion的UML类图

        话不多说直接上图,让我们一睹BeanDefinition的大家族。原谅笔者不才无法用一张UML类图概括完整个BeanDefinition家族

  AnnotatedGenericBeanDefinitionUML类图

                                                                     AnnotatedGenericBeanDefinition UML类图

                                                                        ChildBeanDefinition UML类图

                                                                        RootBeanDefinition UML类图

Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。BeanDefintion是Spring提供的将我们使用xml或者注解修饰的需要spring管理的bean实例统一使用BeanDefintion抽象模式存放,并同时提供有关bean的其他属性信息(spring定义的),注入类型,是否懒加载 ,scope等等,从而便于spring管理和使用。

2、BeanDefintion家族类详解

     2.1、通用接口

 BeanDefintion实现类都会直接或者间接的继承如下接口:    

  1.  AttributeAccessor 接口提供相关属性attribute的设置和读取操作设置属性可以通过xml的<meta key="" value=""/>设置
  2.  BeanMetadataElement接口获取一个包含元数据元素的配置源对象 
  3.  AttributeAccessorSupport抽象类 实现了AttributeAccessor接口  使用Map来提供属性的访问和操作
  4.  BeanMetadataAttributeAccessor类  继承AttributeAccessorSupport 实现BeanMetadataElement  新增的功能是访问BeanMetadataAttribute类型的属性。

    2.2、BeanDefintion接口

            BeanDefintion是Beandefintion系列的顶层接口,继承AttributeAccessor接口和BeanMetadataElement接口 所以具备了访问bean属性 以及获取源对象的功能。  spring将我们需要托管的bean都转换为 BeanDefinition 该接口中包含如下属性setter getter接口方法:

	 parentName: 父beanDefinition 名
	 beanClassName: bean实例对象的class名字
         scope: 单例或者原型
	 lazyInit: 是否懒加载
	 dependsOn: 该bean定义所有依赖的beanName 列表
	 autowireCandidate:是否为注入的候选者    
	    autowire-candidate 属性设置为 false,  这样容器在查找自动装配对象时 将不考虑该 bean,
	    即它不会被考虑作为其他 bean 自动装配的候选者,
	    但是该 bean 本身还是可以使用自动装配来注入其他的 bean
	 primary:是否为唯一的注入候选者
	 factoryBeanName: 创建该bean的工厂BeanName
	 factoryMethodName:创建该bean的工厂MethodName
	 ConstructorArgumentValues:构造参数包装类
	 MutablePropertyValues:可变属性列表
	 scope:是否单例 是否原型
	 role: 用于标识Bean的分类 有三种标识1、用户定义的bean ROLE_APPLICATION 2、某些复杂的配置ROLE_SUPPORT 3、完全内部使用ROLE_INFRASTRUCTURE
	 description 获取描述
         description:返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
         originatingBeanDefinition:获取原始的bean定义

    2.3、AbstractBeanDefintion抽象类

            AbstractBeanDefintion抽象类完全的实现了BeanDefinition中定义的所有接口(提供了默认的实现方式),同时也提供了一些扩展字段qualifiers属性、MethodOverrides属性等。

// Bean 的Class 对象
private volatile Object beanClass;

// bean 的作用范围, 对应 bean 属性 scope (常见的就是单例/原型)
private String scope = SCOPE_DEFAULT;

// 是否是抽象, 来自 bean 属性的 abstract(抽象的类是不能直接生成对象)
private boolean abstractFlag = false;

// 是否延迟加载, 对应 bean 属性 lazy-init (值是否在使用 Bean的时候才正真的创建 Bean)
private boolean lazyInit = false;

// 自动注入模式, 对应 bean 属性 autowire (这个属性主要指 XML 描述的 beanDefinition, 在生成bean的对吼阶段, 获取容器中的对象, 自动装配在 BeanDefinition 对应的 Field 上)
private int autowireMode = AUTOWIRE_NO;

// 依赖检查, Spring 3.0 后 弃用这个属性
private int dependencyCheck = DEPENDENCY_CHECK_NONE;

// 用来表示一个 bean 的实例化依靠另一个 bean 先实例化(PS: 这个很少使用了)
private String[] dependsOn;

/**
 *  autowire-candidate 属性设置为 false, 
 *  这样容器在查找自动装配对象时
 *  将不考虑该 bean, 即它不会被考虑作为其他 bean 
 *  自动装配的候选者, 但是该 bean 
 *  本身还是可以使用自动装配来注入其他的 bean
 */
private boolean autowireCandidate = true;

// 自动装配时当出现多个 bean 候选者时, 将作为首候选者 (PS: 使用比较少)
private boolean primary = false;

// 用于记录 Qualifier, 对应子元素 qualifier(当使用 @Autowired 时, 有多个候选Bean 时, 就通过这个Qualifier 来进行区分)
private final Map<String, AutowireCandidateQualifier> qualifiers =
        new LinkedHashMap<String, AutowireCandidateQualifier>(0);

// 允许访问非公开的构造器和方法, 程序设置  (PS: 用得比较少)
private boolean nonPublicAccessAllowed = true;

/**
 * 是否以一种宽松的模式解析构造函数, 默认 true
 * 如果是 false, 则在如下情况
 * interface ITest()
 * class ITestImpl implement ITest();
 * class Main {
 *     Main(ITest i) {}
 *     Main(ITestImpl i) {}
 * }
 * 抛出异常, 因为 Spring 无法准确确定哪个构造函数
 * 程序设置
 *
 * lenient 宽大, 仁慈
 */
private boolean lenientConstructorResolution = true;

/**
 * 对应 bean 属性 factory-bean 用法 (PS: 这里涉及 FactoryBean 这个概念, 这个类主要是解决: 创建一个类, 但创建这个类的过程比较长/条件比较多, 这时候就使用同一的抽象工厂模式(FactoryBean对象) 来创建对象)
 * <bean id="instanceFactoryBean" class="example.chapter3.InstanceFactoryBean />
 * <bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime" />
 */
private String factoryBeanName;

// 对应 bean 属性 factory-method
private String factoryMethodName;

// 记录构造函数注入属性, 对应 bean 属性 constructor-arg
private ConstructorArgumentValues constructorArgumentValues;

// 普通属性集合 (在XML 中定义Bean的信息时, 通常propertyValues里面有很多依赖信息)
private MutablePropertyValues propertyValues;

// 方法重写的持有者, 记录 lookup-method, replaced-method 元
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值