容器中的工廠Bean:
此處的工廠Bean與前面介紹的實例工廠方法創(chuàng)建Bean、靜態(tài)工廠創(chuàng)建Bean有所區(qū)別:
前面的那些工廠是標準的工廠模式游岳,Spring只是負責(zé)調(diào)用工廠方法來創(chuàng)建Bean實例块攒;
此處工廠Bean是Spring的一種特殊Bean硬猫,這種工廠Bean必須實現(xiàn)FactoryBean接口。
FactoryBean接口是工廠Bean標準的工廠Bean的接口曲初,實現(xiàn)該接口的Bean只能當工廠Bean使用卒蘸,當我們將工廠Bean部署在容器中雌隅,并通過getBean()方法來獲取工廠Bean,容器不會返回FactoryBean實例而是FactoryBean的產(chǎn)品。
FactoryBean提供了三個方法:
<li>Object getObject();
<li>Class getObjectType();
<li>boolean isSingleton();
例如:
public class PersonFactory implements FactoryBean{
Person p = null;
public Object getObject() throws Exception{
if(p==null){
p = new Chinense();
return p;
}
}
public Class getObjectType(){
return Chinese.class;
}
public boolean isSingleton(){
return true;
}
}
<!--配置一個FactoryBean,和普通的Bean一樣-->
<bean id="chinese" class=""/>
public static void main(String args[]){\
//以classpth下的bean.xml創(chuàng)建Reource對象
ClassPathResource re = new ClasspathResource("bean.xml");
//創(chuàng)建BeanFactory
XmlBeanFactory factory = new XmlBeanFactory(re);
Person p = (Person)factory.getBean("chinese");
//如需要獲取FactoryBean本身則應(yīng)該在bean id前加&
Person p = (Person)factory.getBean("&chinese");
}
對于初學(xué)者可能無法體會到工廠bean的作用恰起,實際上修械,F(xiàn)actoryBean是Spring中非常有用的接口。例如:TransationProxyFactroyBean,這個工廠轉(zhuǎn)為目標Bean創(chuàng)建事務(wù)代理.
6.深入理解依賴關(guān)系配置
<li>組件與組件之間的耦合检盼,采用依賴注入管理祠肥,但是普通的javabean屬性值,應(yīng)直接在代碼里設(shè)置梯皿。
<li>對于singleton作用域的bean,如果沒有強制取消其預(yù)初始化行為县恕,系統(tǒng)會在創(chuàng)建Spring容器時預(yù)初始化所有的singleton作用域的bean东羹,與此同時,該bean依賴的bean也一起被實例化忠烛。
<li>BeanFactory與ApplicationContext實例化容器中的bean的時機不同属提,前者等到程序需要Bean實例才創(chuàng)建Bean,后者會預(yù)初始化容器中的所有Bean。
因為采用ApplicationContext作為Spring的容器美尸,創(chuàng)建容器時冤议,會創(chuàng)建容器中所有singleton作用域的所有bean,因此可能需要更多的系統(tǒng)資源师坎,但是一旦創(chuàng)建成功恕酸。應(yīng)用后面的 響應(yīng)速度會很快,因此胯陋,對于普通的javaEE而言 蕊温,建議使用ApplicationContext作為Spring的容器。
Bean實例4種屬性值的設(shè)置:
①設(shè)置普通屬性值value
略
②配置合作者Bean ref
可以為ref元素指定兩個屬性:bena遏乔、Local
bean:引用在不同一份XML配置文件中的其他Bean實例的ID屬性值义矛;
Local:引用同一份XML配置文件的其他Beanid屬性值。
也可以不配置以上兩個屬性盟萨。
③組合屬性名稱:
public class A{
private Person p = new Person();
set/get....
}
`Spring配置文件`
<bean id="a" class="A">
<property name="p.name" value="aaa"/>
</bean>
④注入嵌套Bean:
>```
<bean id="" class="">
< property name="">
//屬性為嵌套Bean 不能由Spring容器直接訪問凉翻,因此沒有id屬性
<bean class="..."/>
</property>
</bean>
⑤注入集合值:
<list>
<value></value>
<value></value>
</list>
<map>
//每一個entry配置一個key-value對
<entry>
<key>
<value>.</value>
</key>
<value></value>
</entry>
</map>
<set>
<value></value>
<bean></bean>
<ref local=""/>
</set>
<props>
<prop key="">.....</prop>
<prop key="">.....</prop>
</props>
⑥注入方法返回值:
public class ValueGenrator{
public int getValue(){
return 6;
}
public static int getStaticValue(){
return 9;
}
}
<bean id="valueGenrator" class="lee.ValueGenrator"/>
<bean id="son1" class="Son">
<property name="age">
<bean class="org.springframework.bean.factory.congfig.MethodInvokignFactoryBean">
//配置非靜態(tài)方法
<property name="targetObject" ref="valueGenrator"/>
//配置靜態(tài)方法
<property name="targetMehtod" value="getStaticValue/>
</property>
</bean>
---
**強制初始化Bean**
>Spring有一個默認的規(guī)則,總是先初始化主調(diào)Bean捻激,然后在初始化依賴Bean制轰。
為了指定Bean在目標Bean之前初始化,可以使用**depends-on**屬性.
>`大多數(shù)情況下`铺罢,Bean之間的依賴關(guān)系非常直接艇挨,Spring容器在返回Bean實例之前,完成Bean依賴關(guān)系的注入韭赘。假如Bean A依賴于Bean B缩滨,程序請求Bean A時,Spring容器會自動先初始化Bean B,再將Bean B注入Bean A脉漏,最后將具備完整依賴的Bean A返回給程序苞冯。
`在極端的情況下`,Bean之間的依賴不夠直接侧巨。比如某個類的初始化塊中使用其他Bean舅锄,Spring總是先初始化主調(diào)Bean,執(zhí)行初始化塊時還沒有實例化主調(diào)Bean司忱,被依賴的Bean還沒實例化皇忿,此時將引發(fā)異常。
>為了讓指定Bean在目標Bean之前初始化坦仍,可以使用 depends-on 屬性鳍烁,該屬性可以在初始化主調(diào)Bean之前,強制初始化一個或多個Bean繁扎。
<bean id="beanOne" class="ExampleBean" depends-on="manager">
<property name="manager" ref="manager"/>
</bean>
<bean id="manager" class="ManagerBean"/>