Spring-Context之七:使用p-namesapce和c-namespace簡化bean的定義

黃博文發表於2014-03-25

在Spring中定義bean的方式多種多樣,即使使用xml的方式來配置也能派生出很多不同的方式。

比如如下的bean定義:

1
2
3
4
5
6
7
8
9
10
11
12
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="person" class="Person">
        <property name="name" value="Tom"/>
        <property name="age" value="20"/>
    </bean>

</beans>

這樣的bean有三行,通過使用p-namespace以後可以簡化為一行。

1
2
3
4
5
6
7
8
9
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person" class="Person" p:name="Tom" p:age="20"/>

</beans>

那麼什麼是p-namespace那?它的作用就是使用xml中的元素屬性取代<property/>節點來定義bean的屬性。這個神奇的p是什麼東西那?它其實是使用了namespace的xml擴充套件配置格式。beans的配置格式是定義在一個xsd格式中的(即 http://www.springframework.org/schema/beans/spring-beans.xsd),但p卻沒有一個xsd格式檔案與其對應,但是它可以被spring核心解析處理。

上面只是演示了對屬性為普通值的時使用p-namespace的注入,如果屬性為另一個bean的引用時該如何處理那?很簡單。

這是使用正常方式注入屬性。

1
2
3
4
5
6
    <bean id="messageService" class="SimpleMessageService"/>
    <bean id="messageHandler" class="MessageHandler">
        <property name="messageService">
            <ref bean="messageService" />
        </property>
    </bean>

使用p-namespace後是這樣的。

1
2
    <bean id="messageService" class="SimpleMessageService"/>
    <bean id="messageHandler" class=“MessageHandler” p:messageService-ref=“messageService”/>

加上-ref字尾即表示是對一個bean的引用。

那既然setter方法注入bean可以使用p-namespace,那麼構造器方式注入有沒有相應的簡寫那?答案是肯定的,那就是c-namespace,原理和使用方法與p-namespace大同小異。

使用c-namespace前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="person" class="Person">
        <constructor-arg name="name">
            <value>Tom</value>
        </constructor-arg>
        <constructor-arg name="age" value="20"/>
    </bean>

</beans>

使用c-namespace後:

1
2
3
4
5
6
7
8
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="person"  c:name="Tom" c:age="20"/>
</beans>

也可以使用-ref字尾來表示對另一個bean的引用。

1
2
 <bean id="messageService" class="SimpleMessageService"/>
    <bean id="messageHandler" class="MessageHandler" c:messageService-ref="messageService"/>

在前面章節講解構造器注入時,可以使用構造引數索引來注入依賴,c-namespace也支援這一方式。

1
2
3
4
5
6
7
8
9
10
11
12
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="person”  c:_0="Tom" c:_1="20"/>

<bean id="messageService" class="SimpleMessageService"/>
<bean id="messageHandler" class="MessageHandler" c:_0-ref="messageService"/>

</beans>

怎麼樣,是不是很強大啊。但是太過強大也容易傷人傷己。在專案中使用這些技巧之前最好先和專案成員達成一致。

本例中的原始碼請在我的GitHub上自行下載。

相關文章