您的位置:首页 > 编程语言 > Java开发

spring源代码分析(3):关于BeanDefinition的思考

2009-04-09 09:45 351 查看
spring2.0的源码中的BeanDefinition的结构类图和上一节有所不同;如下:


 从类图中,我们可以看见AbstractBeanDefinition虽然没有Abstract方法,但是依旧声明了Abstract类,那是因为在整个系统中,他在认知中不可能实例化一个具体的类,那我们就要在设计阶段将他给限定下来; 最后在系统我们可以生成的类,就只有两种,分别是 RootBeanDefinition:对应于Xml文件中的一个顶级的(即没有Parent)的Bean定义; ChildBeanDefinition:对应于一个子Bean定义,他是从一个已有的Bean继承而来;

 

public ChildBeanDefinition(String parentName) {
        super();
        this.parentName = parentName;
    }

    public ChildBeanDefinition(String parentName, MutablePropertyValues pvs) {
        super(null, pvs);
        this.parentName = parentName;
    }

  
    public ChildBeanDefinition(
            String parentName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

        super(cargs, pvs);
        this.parentName = parentName;
    }

   
    public ChildBeanDefinition(
            String parentName, Class beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

        super(cargs, pvs);
        this.parentName = parentName;
        setBeanClass(beanClass);
    }

  
    public ChildBeanDefinition(
            String parentName, String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

        super(cargs, pvs);
        this.parentName = parentName;
        setBeanClassName(beanClassName);
    }

  
    public String getParentName() {
        return parentName;
    }

 

 

在这里有对父Bean的访问和联系; AttributeAccessor是一个对属性进行修改,增加,删除功能的接口,在AccessorSupport中,我们维护一个Map类型的属性作为属性的容器; 在查看了源码以后,提出几点疑问并且尝试自己解答: (1): BeanDefinition继承了两个接口,实现了多继承,为什么我们不能采用一下类图结构来达到Accessor和

BeanMetadataSource功能的组合:

 

 

 



答:这是因为我们在划分接口的时候,以最小的功能位细粒度,所以在这里我们抽取出来两个接口,但是在功能进行组合的时候,我们的接口采用继承还是“集成”,首先取决与分类学的角度来看待问题,两者之间是否是平行关系还是“副词/形容词”修饰的关系;比如说在BeanFactory中有 HierarchicalBeanFactory继承于BeanFactory接口,那么,我们把HierarchicalBeanFactory看成是 “拥有等级功能” 的 “Bean工厂” 这就是修饰的概念,系统中没有一个叫做“等级功能”的单独的接口体系,他是对BeanFactory的进一步细化; 然而,在系统中,我们存在一个叫做"属性访问器"和"Bean元信息元素"的接口,属性访问是一个角色,是名词,代码一组实际存在的功能对象的共性,如PropertyValues类。

在这里,若AttributeAccessor继承BeanMetadataElement,那么就造成了接口污染,我们无法单独继承和实现AttributeAccessor;所以在这里我们选择BeanDefinition分别具有两种接口;

 

 (2):在实现AbstractBeanDefinition的时候,我们继承了BeanDefinition接口,就表示我们间接的实现了AttributeAccessor 接口,为什么我们还要抽象出一个AbstractAccessorSupport来,并且继承这个抽象类呢?这不会是一种重复继承吗?

答:这是为了达到复用的目的,这个问题我们从重构的角度比较好分析;在重构一书中,我们可以清晰的看到,如果两个类中间的代码有大多数相同,那么我们应该尝试把这些代码抽取出来成为一个类,然后继承于他; 由于PropertyValues中和AbstractBeandefinition中有关AttributeAccessor的代码都是相同的,所以我们有理由他这部分抽取出来成为一个抽象类(不能实例化,仅仅提供代码的复用),在这里,不存在重复继承因为代码复用的手段一种是集成,一种是继承,在这里,因为他们有共同的一个实现接口,所以采用继承的手段来达到复用;

 

(3):我们可以看到在childBeanFactory的代码中有getParentName方法是在接口BeanDefinition中不存在的,而在AbstractBeanFactory中的getMegerDefinition中,我们频繁的出现类BeanDefinition代码的instanceOf 类型判断来调用 getParentName方法,在这里,我们可不可以在BeanDefinition中实现这个方法,并且在RootBeanDefinition中空实现这个方法,利用多状来进行类型判断;

 答:不好,因为空实现不代表不具有这个功能,接口只所以抽象出来是因为他代表了实现这个接口的类的共性,既然有类不具有这种功能,那么我们就不应该把他放在接口的定义里面,这只能说明拥有这中功能的类,是这个顶层接口的扩展和特例,那么我们可以采取这种手段来实现:

 



 

这里,由于我们ChildBeanDefinition只有一个唯一的实现,并且以后扩展的可能性也很小,所以我们并不一定要拿出一个抽象的接口层:IChildbeanDefinition而直接得到ChildBeanDefinition;(找出变化和扩展点,抽象他) 文章出处:http://www.diybl.com/course/3_program/java/javaxl/2008912/142130.html 文章出处:http://www.diybl.com/course/3_program/java/javaxl/2008912/142130.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐