2015年12月18日 星期五

ref 的 local、bean、parent 和 ref 與 idref 的區別(Spring3.x 六)

※ref 的 local、bean、parent

參考文件
官方的大概意思是說
※local:抓自己xml上的id
※bean:抓全部的xml上的id或name
※parent:抓爸爸的xml的id或name


Book.java

public class Book {
    private Comic comic;
    // setter/getter...
    }
}

Comic.java

public class Comic {
    private String comicName;
    // setter/getter...
}


 papa.xml

<bean id="cName" class="book.vo.Comic">
    <property name="comicName" value="滾球王" />
</bean>

son.xml

<bean id="cName" class="book.vo.Comic">
    <property name="comicName" value="七龍珠" />
</bean>
    
<bean id="local" class="book.vo.Book">
    <property name="comic">
        <ref local="cName" />
    </property>
</bean>
    
<bean id="bean" class="book.vo.Book">
    <property name="comic">
        <ref bean="cName" />
    </property>
</bean>
    
<bean id="parent" class="book.vo.Book">
    <property name="comic">
        <ref parent="cName" />
    </property>
</bean>


測試類:

BeanFactory papa = new XmlBeanFactory(new ClassPathResource("papa.xml"));
BeanFactory son = new XmlBeanFactory(new ClassPathResource("son.xml"), papa);
    
Book local = (Book) son.getBean("local");
Book bean = (Book) son.getBean("bean");
Book parent = (Book) son.getBean("parent");
    
System.out.println(local.getComic().getComicName());
System.out.println(bean.getComic().getComicName());
System.out.println(parent.getComic().getComicName());

結果:
七龍珠
七龍珠
滾球王

※如果將son.xml上的id="cName",改成name="cName",結果還是一樣,想不到local還是可以抓到name的

※如果將son.xml上的cName整個刪除,local和bean的結果都抓到滾球王,想不到local還是可以抓到其他的xml

※如果將papa.xml的cName刪除,parent會發生例外,這點和官方說的一樣

※看來都是local和官方的說法不一樣,感覺上local和bean沒區別,也許是版本問題吧!不過聽說spring 4已將local移除了



剛剛的測試類,裡面的BeanFactory已經deprecation了,所以還可以用如下的方法
ApplicationContext papa = new ClassPathXmlApplicationContext("papa.xml");
ApplicationContext son = new ClassPathXmlApplicationContext(new String[] { "son.xml" }, papa);
    
Book local = (Book) son.getBean("local");
Book bean = (Book) son.getBean("bean");
Book parent = (Book) son.getBean("parent");
    
System.out.println(local.getComic().getComicName());
System.out.println(bean.getComic().getComicName());
System.out.println(parent.getComic().getComicName());
    
((ClassPathXmlApplicationContext) son).close();

※測試的結果也和上面一樣


※用import的方式

<import resource="papa.xml" />
    
<bean id="cName" class="book.vo.Comic">
    <property name="comicName" value="七龍珠" />
</bean>
    
<bean id="local" class="book.vo.Book">
    <property name="comic">
        <ref local="cName" />
    </property>
</bean>
    
<bean id="bean" class="book.vo.Book">
    <property name="comic">
        <ref bean="cName" />
    </property>
</bean>

※這和官方說的父子沒什麼關係,所以parent不能使用

※papa.xml的內容和上面的一樣

※import的id可以重覆

※如果自己的xml有就抓,沒有就會去import找,再沒有就出錯誤訊息,和上面的一樣




※ref 與 idref 的區別

ref:上面就有了,就是個參考
idref:參考文件下面一點有個The idref element,有說是個String,不是參考

applicationContext.xml

<import resource="papa.xml" />
    
<bean id="co" class="book.vo.Comic" />
    
<bean id="book" class="book.vo.Book">
    <property name="bookName">
        <!-- <idref local="co" /> -->
        <value>co</value>
    </property>
</bean>

測試類

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    
Book book = (Book) appContext.getBean("book");
System.out.println(book.getBookName());
    
((ClassPathXmlApplicationContext) appContext).close();

※也就是說idref和value一樣,就差在idref裡面的字,必需在import裡或者自己的xml裡的id(name我試過也OK)有才行,有就是多個驗證的功能,用的地方應該很少,官方有說它帶來的價值是在AOP的攔截器

※idref有local和bean,沒有parent屬性,local和bean和上面的測試一樣,我測不出兩者的差別,一樣都是自己有就抓,沒有就往import裡找,找不到就出錯

※idref和value只能選擇其一

沒有留言:

張貼留言