1. 程式人生 > >【Spring源碼解讀】bean標簽中的屬性(二)你可能還不夠了解的 abstract 屬性和 parent 屬性

【Spring源碼解讀】bean標簽中的屬性(二)你可能還不夠了解的 abstract 屬性和 parent 屬性

() 語義 valueof 更多 vat assert getheight 它的 src

abstract 屬性說明

abstract 在java的語義裏是代表抽象的意思,用來說明被修飾的類是抽象類。在Spring中bean標簽裏的 abstract 的含義其實也差不多,表示當前bean是一個抽象的bean,從而不會為它生成實例化對象。

聲明一個bean,但是又不讓它實例化???

技術分享圖片

莫方,存在即合理,abstract 屬性存在必定有其存在的意義,且聽我慢慢道來。

parent 屬性說明

在此之前,我們先說一下另一個屬性: parent ,顧名思義,就是一個認爸爸的屬性,用來表明當前的bean的老爸是誰,這樣就能順利的繼承它的遺產。。。emmm,說錯了,繼承它的屬性。就像這樣:

<bean id="abstractBean" class="com.frank.spring.bean.parent.ParentBean" abstract="true">
    <property name="name" value="Frank" />
    <property name="age" value="18" />
</bean>

<bean id="childBean" class="com.frank.spring.bean.parent.ChildBean" parent="abstractBean">
    <property name="name" value="son"/>
    <property name="height" value="180"/>
</bean>

這樣我們就有了一個父bean和一個子bean,在childBean中,我們只設置了name和height屬性,但由於在xml文件中,通過parent屬性給它安排了一個老爸是abstractBean,所以默認會繼承它的age屬性的值,也就是18。在子bean中,可以覆蓋父bean中的屬性,比如這裏的name,在childBean中就重新設置了值。

技術分享圖片

來測試一下:

@Test
public void testAbstract() {
    ApplicationContext context = new ClassPathXmlApplicationContext("test-bean.xml");
    ChildBean childBean = (ChildBean) context.getBean("childBean");
    Assert.assertEquals(childBean.getName(), "son");
    Assert.assertEquals(childBean.getAge(), Integer.valueOf(18));
    Assert.assertEquals(childBean.getHeight(), Integer.valueOf(180));
}

以下是ParentBean和ChildBean的定義:

public class ParentBean {
    private String name;
    private Integer age;

    //省略getter和setter方法
}

public class ChildBean {
    private String name;
    private Integer age;
    private Integer height;

    //省略getter和setter方法
}

聰明的你一定發現了,這兩個類並不一定要有實際的繼承關系,可以是兩個普通的類。甚至,parent

屬性所指向的bean可以不用設置某個具體的類,而只設置它是屬性,就像這樣:

<bean id="abstractParent" abstract="true">
    <property name="name" value="Frank" />
    <property name="age" value="18" />
</bean>

<bean id="testChild" class="com.frank.spring.bean.parent.ChildBean" parent="abstractParent">
    <property name="name" value="son"/>
    <property name="height" value="180"/>
</bean>
@Test
public void testAbstractParent() {
    ApplicationContext context = new ClassPathXmlApplicationContext("test-bean.xml");
    ChildBean childBean = (ChildBean) context.getBean("testChild");
    Assert.assertEquals(childBean.getName(), "son");
    Assert.assertEquals(childBean.getAge(), Integer.valueOf(18));
    Assert.assertEquals(childBean.getHeight(), Integer.valueOf(180));
}

可以看到這次我們設置的abstractParent並沒有為其指定類名,我們也能將它做為parent屬性的值。

abstract 屬性的作用

在Spring中, abstract 屬性一般是用來聲明抽象bean,將一些公共的屬性放到一塊,這樣就能減少重復的代碼。所以在標簽中,可以這樣設置:

<bean id="abstractBean" class="com.frank.spring.bean.parent.ParentBean" abstract="true">
    <property name="name" value="Frank" />
    <property name="age" value="18" />
</bean>

<bean id="childA" class="com.frank.spring.bean.parent.ChildBean" parent="abstractBean">
    <property name="name" value="GG"/>
    <property name="height" value="180"/>
</bean>

<bean id="childB" class="com.frank.spring.bean.parent.ChildBean" parent="abstractBean">
    <property name="name" value="DD"/>
    <property name="height" value="185"/>
</bean>

這樣,abstractBean就起到了一個模板的作用,可以減少重復定義,這裏只有簡單的幾個屬性,所以可能看起來不是很直觀,可以想象一下,如果abstractBean中有一二十個公用屬性,是不是可以少寫不少代碼呢?

總結

abstractparent 屬性可以當做用來減少xml重復代碼的方法,可以將一些bean的公共屬性抽取出來,放到一個公共的bean中,然後使用上面的栗子進行配置,來讓xml文件更加簡潔。

值得註意的是,parent屬性配置的bean之間,並不一定需要有實際的繼承關系,更多的是屬性的繼承。被設置為parent的bean甚至可以不用映射到某一個具體的類,而僅僅將其當做屬性模板來使用。

文章持續更新中,歡迎關註我的公眾號留言交流。

技術分享圖片

【Spring源碼解讀】bean標簽中的屬性(二)你可能還不夠了解的 abstract 屬性和 parent 屬性