※工廠方法、lazy、初始、結束
Book.java
public class Book { public static String getBookName() { String s = "七龍珠"; System.out.println(s); return s; } public void ooo() { System.out.println("初始"); } public void xxx() { System.out.println("結束"); } }
applicationContext.xml
<bean id="book1" class="book.vo.Book" init-method="ooo" destroy-method="xxx" /> <bean id="book2" class="book.vo.Book" factory-method="getBookName" lazy-init="true" /> <bean id="ca" class="java.util.Calendar" factory-method="getInstance" /> <bean id="result" factory-bean="ca" factory-method="getTime" />
測試類
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Date date = (Date) appContext.getBean("result"); System.out.println(date); ((ClassPathXmlApplicationContext) appContext).close();
結果:
初始
Thu Dec 24 15:32:06 CST 2015
結束
※如果將book2的lazy拿掉,就會印出七龍珠了,或者呼叫book2才會去抓
※book2、ca、result可以用如下的想法比較容易了解
// book2 Book.getBookName(); // ca Date date = Calendar.getInstance().getTime(); //result date.getDate();
※getBookName()必需提供回傳值,否則會出「needs to have a non-void return type!」的錯
※scope 使用 prototype 時,在getBean 時才會去抓值;而 scope 使用預設的 singleton 在 new ClassPathXMLApplicationContext 時就會去抓,如果想和 prototype 一樣,可以用lazy="true"
※ init-method 裡的方法至少要 private void xxx(),不能有參數,如果沒有此方法會報錯
destroy-method 一定要將 ApplicationContext close 才會呼叫,但要將ApplicationContext 強轉成有 close 方法的子類,而且也必須是 singleton,annotation 用的是 @Bean
※如果有很多 class 都想用 init-method 或 destroy-method,每一個都要設很麻煩,所以 Spring 有提供設定,在 beans 裡用 default-init-method、default-destroy-init-method,在設定完 bean class 時才會呼叫,而且沒有寫方法,也不會報錯
※FactoryBean 介面
public class Book { private String bookName; private int bookMoney; public Book() {} public Book(int bookMoney, String bookName) { this.bookMoney = bookMoney; this.bookName = bookName; } //setter/getter... } ------------------------------ public class BookFactoryBean implements FactoryBean<Book> { @Override public Book getObject() throws Exception { return new Book(90, "寶島少年"); } @Override public Class<Book> getObjectType() { return Book.class; } @Override public boolean isSingleton() { return true; } }
※
※
<bean id="b" class="xxx.ooo.Book" p:bookName="七龍珠" p:bookMoney="65" /> <bean id="bfb" class="xxx.ooo.BookFactoryBean" />
※getBean("b") 時是之前的做法,使用 getBean("bfb") 就能看見效果了
※繼承
<bean id="book1" class="book.vo.Book" p:name="資治通鑑" p:money="2000" p:color="紅" p:size="A4" /> <bean id="comic1" class="book.vo.Comic" p:name="遊戲王" p:money="65" p:color="紅" p:size="A4" /> <bean id="book2" class="book.vo.Book" p:name="資治通鑑" p:money="2000" p:color="紅" p:size="A4" abstract="true" /> <bean id="comic2" class="book.vo.Comic" p:name="遊戲王" p:money="65" parent="book2" />
※book1和comic1有兩個屬性一樣,這時可以透過繼承的方法,變成book2和comic2,這時只要在測試類,呼叫comic2的color或size即可取得父類的值,當然重點是abstract和parent
※depends-on
<bean name="dao" class="xxx.Dao" depends-on="database" /> <bean id="database" class="ooo.xxx.Database" />
※dao在連資料庫時,必需取得database,設定depends-on可以保證database先實例化好再實例化dao
※scope
<bean id="book1" class="book.vo.Book" scope="singleton" /> <bean id="book2" class="book.vo.Book" scope="prototype" />
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println(appContext.getBean("book1")); System.out.println(appContext.getBean("book1")); System.out.println(appContext.getBean("book2")); System.out.println(appContext.getBean("book2")); ((ClassPathXmlApplicationContext) appContext).close();
※結果
book.vo.Book@6df97b55
book.vo.Book@6df97b55
book.vo.Book@3cbbc1e0
book.vo.Book@35fb3008
※scope="singleton"為預設
※可以看出結果一、二行一模一樣,因為它是singleton
※只有用getBean才會有single的效果哦,如果用new或者反射的invoke就不會一模一樣了
※還有三種request、session、global session,都是用在web的
沒有留言:
張貼留言