Spring3.0官網文檔學習筆記(七)--3.4.2

3.4.2 依賴與配置的細節
    3.4.2.1  Straight values (primitives, Strings, and so on)
    JavaBeans PropertyEditors被用來轉換這些value到實際的類型。?

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<!-- results in a setDriverClassName(String) call -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="masterkaoli"/>
</bean>

    使用p-namespace使得拼寫更加簡潔(但是拼寫錯誤會在運行時才被發現,而不是在編輯時,除非使用Intellij IDEA或者SpringSource Tool Suite)

<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-3.0.xsd">

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close"
      p:driverClassName="com.mysql.jdbc.Driver"
      p:url="jdbc:mysql://localhost:3306/mydb"
      p:username="root"
      p:password="masterkaoli"/>

</beans>
    另外一種配置(這種模式,Spring容器將element元素轉成java.util.Properties實例通過使用JavaBeans PropertyEditor機制,在這種配置下,Spring團隊建議用這種方法):

<bean id="mappings"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

 <!-- typed as a java.util.Properties -->
 <property name="properties">
    <value>
       jdbc.driver.className=com.mysql.jdbc.Driver
       jdbc.url=jdbc:mysql://localhost:3306/mydb
    </value>
 </property>
</bean>


    關於idref元素,被用於<constructor-arg/>或者<property/>元素中,是一種防錯措施。

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
  <property name="targetName">
      <idref bean="theTargetBean" />
  </property>
</bean>
<bean id="theTargetBean" class="..." />

<bean id="client" class="...">
  <property name="targetName" value="theTargetBean" />
</bean>
     以上第一種方案比第二種方案好。理由:第一種配置能使得spring在部署的時候驗證被引用的bean是否存在;第二種則沒有,只有等這個bean被初始化的時候纔會去驗證。

     此外,如果被引用的bean再同一個xml單元,而且bean的名字就是bean的id,那麼可以使用local屬性。這樣一來允許xml解析器更早的去驗證bean。

<property name="targetName">
 <!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown -->
 <idref local="theTargetBean"/>
</property>
3.4.2.2 對其他beans的引用
    ref元素作爲<constructor-arg/>或者<property/>的一個屬性。
    ref元素的bean屬性可以跟對應bean的id屬性一致,或者是對應bean的其中一個name一致。
    ref元素的local屬性的值要跟對應bean的id屬性一致。
    ref元素的parnet屬性的值要跟對應bean的id屬性一致,或者是對應bean的其中一個name一致。而且對應bean要存在於當前容器的父容器之中:

<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
  <!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService"  <-- bean name is the same as the parent bean -->
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref parent="accountService"/>  <!-- notice how we refer to the parent bean -->
    </property>
  <!-- insert other configuration and dependencies as required here -->
</bean>
3.4.2.3 內部beans
    <bean/>元素存在於<property/>或<constructor-arg/>元素中,就稱之爲內部bean。
<bean id="outer" class="...">
<!-- instead of using a reference to a target bean, simply define the target bean inline -->
<property name="target">
  <bean class="com.example.Person"> <!-- this is the inner bean -->
    <property name="name" value="Fiona Apple"/>
    <property name="age" value="25"/>
  </bean>
</property>
</bean>
    內部bean不需要聲明一個id或者name,容器會忽略掉這些屬性。同時忽略掉scope屬性,它的scope是prototypes。

3.4.2.4 集合

<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property name="adminEmails">
  <props>
      <prop key="administrator">[email protected]</prop>
      <prop key="support">[email protected]</prop>
      <prop key="development">[email protected]</prop>
  </props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
  <list>
      <value>a list element followed by a reference</value>
      <ref bean="myDataSource" />
  </list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
  <map>
      <entry key="an entry" value="just some string"/>
      <entry key ="a ref" value-ref="myDataSource"/>
  </map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
  <set>
      <value>just some string</value>
      <ref bean="myDataSource" />
  </set>
</property>
</bean>
    map的key或者value、set的value還可以是以下的任何一個元素:

bean | ref | idref | list | set | map | props | value | null
    集合合併
    從spring2.0開始,就支持集合合併。
    集合合併允許定義父類型<list/>, <map/>, <set/>或 <props/>元素,然後利用子類型<list/>, <map/>, <set/>或 <props/>元素繼承和重寫父集合的值。最終子類型集合的值就是合併後的結果。

<beans>
<bean id="parent" abstract="true" class="example.ComplexObject">
  <property name="adminEmails">
      <props>
          <prop key="administrator">[email protected]</prop>
          <prop key="support">[email protected]</prop>
      </props>
  </property>
</bean>
<bean id="child" parent="parent">
  <property name="adminEmails">
      <!-- the merge is specified on the *child* collection definition -->
      <props merge="true">
          <prop key="sales">[email protected]</prop>
          <prop key="support">[email protected]</prop>
      </props>
  </property>
</bean>
<beans>
    上述結果:

[email protected]
[email protected]
[email protected]
    集合合併後對list會保存順序,對set,map,properties則沒有這一說法。

    集合合併的約束:
    你不能使用不同類型的集合進行合併;
    merge屬性只能放在子類型的集合端;
    集合合併只在spring2.0及以後的版本提供。

    強類型集合(spring在注入前,先判斷accounts的屬性,然後將要注入的值轉成合適的類型注入):

public class Foo {

  private Map<String, Float> accounts;

  public void setAccounts(Map<String, Float> accounts) {
      this.accounts = accounts;
  }
}
<beans>
  <bean id="foo" class="x.y.Foo">
      <property name="accounts">
          <map>
              <entry key="one" value="9.99"/>
              <entry key="two" value="2.75"/>
              <entry key="six" value="3.99"/>
          </map>
      </property>
  </bean>
</beans>
3.4.2.5 null和空字符串 

<bean class="ExampleBean">
<property name="email" value=""/>
</bean>

   上述跟exampleBean.setEmail("")的效果是一樣的;

<bean class="ExampleBean">
<property name="email"><null/></property>
</bean>
  上述跟 exampleBean.setEmail(null)的效果是一樣的;

3.4.2.5 xml使用p-namespace作爲快捷方式
    Spring2.0及之後的版本支持。
    p-namespace並不是被定義在xsd文件,而是隻存在於Spring的core。  

<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-3.0.xsd">

  <bean name="classic" class="com.example.ExampleBean">
      <property name="email" value="[email protected]"/>
  </bean>

  <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="[email protected]"/>
</beans>
<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-3.0.xsd">

  <bean name="john-classic" class="com.example.Person">
      <property name="name" value="John Doe"/>
      <property name="spouse" ref="jane"/>
  </bean>

  <bean name="john-modern"
      class="com.example.Person"
      p:name="John Doe"
      p:spouse-ref="jane"/>

  <bean name="jane" class="com.example.Person">
      <property name="name" value="Jane Doe"/>
  </bean>
</beans>
3.4.2.7 Compound property names(引用對象的屬性注入)

<bean id="foo" class="foo.Bar">
<property name="fred.bob.sammy" value="123" />
</bean>
    叫foo的bean有一個fred屬性,fred對象有一個bob屬性,bob對象有一個sammy屬性。要讓這個配置有效,在foo被創建之後fred、bob、sammy屬性不可以爲null。否則報NullPointerException異常?
    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章