Core模塊主要的功能是實(shí)現(xiàn)了控制反轉(zhuǎn)與依賴(lài)注入、Bean配置和加載。Core模塊中有Beans、BeanFactory、BeanDefinitions、ApplicationContext等概念
BeanFactory
BeanFactory是實(shí)例化、配置、管理眾多bean的容器
在Web程序中用戶(hù)不需要實(shí)例化Beanfactory,Web程序加載的時(shí)候會(huì)自動(dòng)實(shí)例化BeanFactory,并加載所欲的Beans,將各個(gè)Bean設(shè)置到Servlet、Struts的Action中或Hibernate資源中
在Java桌面程序中,需要從BeanFactory中獲得Bean,因此需要實(shí)例化BeanFactory,例如,加載ClassPath下的配置文件:
ClassPathResource res = new ClassPathResource("applicationContext.xml"); XmlBeanFactory factory = new XmlBeanFactory (res); Iservice service= factory.getBean("service"); …… factory.destroySingletons();
或使用文件流加載任意位置的配置文件
InputStream in = new FileInputStream("C:ApplicationContext.xml"); XmlBeanFactory factory = new XmlBeanFactory (in);
或用ClassPathXmlApplicationContext加載多個(gè)配置文件(以字符串情勢(shì)傳入)ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String [] {"applicationContext.xml","applicationContext-part2.xml"} ); BeanFactory factory = (BeanFactory) appContext; //ApplicationContext繼承自BeanFactory接口配置Bean
工廠模式
如果1個(gè)bean不能通過(guò)new直接實(shí)例化,而是通過(guò)工廠類(lèi)的某個(gè)方法創(chuàng)建的,需要把<bean>的class屬性配置為工廠類(lèi)(或吧factory-bean屬性配置為工廠類(lèi)對(duì)象)
<bean id="examBean" class = "examples.MyBeanFactory" method="createInstance" /> <!--等價(jià)于下面的配置--> <bean id="examBean2" factory-bean = "examples.MyBeanFactory" method="createInstance" />
構(gòu)造函數(shù)
如果Bean的構(gòu)造函數(shù)帶有參數(shù),需要指定構(gòu)造函數(shù)的參數(shù)
<bean id = "examBean" class=" examples.ExampleBean"> <constructor-args><ref bean="anotherBeanId"/></constructor-args> <constructor-args><ref bean="anotherBeanId2"/></constructor-args> <constructor-args><value>1</value></constructor-args> </bean>
參數(shù)又前后順序,要與構(gòu)造函數(shù)參數(shù)的順序相同
單態(tài)模式
Bean可以定義是不是為單態(tài)模式,在非單態(tài)模式下,每次要求該Bean都會(huì)生成1個(gè)新的對(duì)象
像數(shù)據(jù)源等1班配置為單態(tài)模式
<bean id="exampleBean" class="examples.ExamleBean" singleton="false"/>property屬性
destroy-method屬性配置關(guān)閉方法,如果有配置,在拋棄Java對(duì)象時(shí)會(huì)調(diào)用該方法,某些數(shù)據(jù)源、SessionFactory對(duì)象都需要用destroy-method配置關(guān)閉方法
<property name="examProperty" value="pValue" />
等價(jià)于<property name="examProperty"> <value>pValue</value> </property>
注意:
<property name="password"> <value></value> </property>
會(huì)將password設(shè)置為"",而不是null,如果想設(shè)置為null應(yīng)當(dāng)為
<property name="password"> <null/> </property><ref>屬性
Spring配置文件的Bean之間可以相互援用,援用時(shí)用<ref>標(biāo)簽配合Bean的id屬性使用
也能夠使用內(nèi)部配置
<bean id="dao" class = "com.clf.DaoImpl"></bean> <bean id="serviceImpl" class="com.clf. serviceImpl"> <property name="dao"> <ref bean="dao"/> </property> </bean>
等價(jià)于內(nèi)部配置<property name="dao"> <bean class="com.clf.DaoImpl"/> </property>除使用<ref>的bean屬性,還可使用local、parent,它們與bean屬性的作用是1樣的,但是,local只能使用本配置文件中的bean,parent只能使用父配置文件中的bean
<list>屬性
<property name="propName"> <list> <value>String、Integer、Double等類(lèi)型數(shù)據(jù)</value> <ref bean="dataSource"/> </list> </property>
<set>屬性
<property name="propName"> <set> <value>String、Integer、Double等類(lèi)型數(shù)據(jù)</value> <ref bean="dataSource"/> </set> </property>
<map>屬性
<property name="propName"> <map> <entry key="key1"> <value>String、Integer、Double等類(lèi)型數(shù)據(jù)</value> </entry> <entry key-ref="key2"> <ref bean="dataSource"/> </entry> </map> </property>
<props>屬性
<property name="propName"> <props> <prop key="url">http://localhost:8080/clf</prop> <prop key="name">clf</prop> </ props > </property>
<destroy-method>和<init-method>屬性
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> …… </bean>
Spring在注銷(xiāo)這些資源時(shí)會(huì)調(diào)用close方法
有些對(duì)象在實(shí)例化以后需要履行某些初始化代碼,但是這些代碼不能寫(xiě)進(jìn)構(gòu)造函數(shù),這時(shí)候候可以把初始化代碼寫(xiě)進(jìn)某個(gè)方法中,并用<init-method>指定該方法
<bean id="c" class="com.clf.SpringExample" init-method="init">depends-on屬性
Spring會(huì)默許依照配置文件里的Bean順序地實(shí)例化Bean,但是有時(shí)候?qū)嵗疉對(duì)象之前需要先實(shí)例化后面的B對(duì)象,這時(shí)候候可使用depends-on屬性強(qiáng)迫先實(shí)例化B對(duì)象
<bean id="a" clas="com.clf.A" depends-on="b"></bean> <bean id="b" clas="com.clf.B"></bean><idref>與<ref>的區(qū)分
<idref>與<ref>的作用是1樣的,都是配置Java對(duì)象的,不同的是,<idref>只有bean與local屬性,沒(méi)有parent屬性
Spring加載XML配置文件時(shí),會(huì)檢查<idref>配置的Bean在不在,而<ref>只會(huì)在第1次調(diào)用時(shí)才會(huì)檢查,換句話說(shuō),如果Bean不存在,<idref>在啟動(dòng)程序時(shí)就會(huì)拋出毛病,而<ref>只會(huì)在運(yùn)行中拋出毛病
<autowire>
可以通過(guò)Bean的autowire屬性設(shè)置自動(dòng)裝配規(guī)則。使用autowire后不需要再用<propertyname="" value="" />顯式地設(shè)置該Bean的屬性、依賴(lài)關(guān)系,Spring會(huì)根據(jù)反射,自動(dòng)尋覓符合條件的屬性,設(shè)置到該Bean上
autowire屬性定義的不是需要自動(dòng)裝配的屬性名,而是自動(dòng)裝配的規(guī)則,1旦配置,所有的屬性都會(huì)遵守autowire定義的規(guī)則
No:即不啟用自動(dòng)裝配。Autowire默許的值。
byName:通過(guò)屬性的名字的方式查找JavaBean依賴(lài)的對(duì)象并為其注入。比如說(shuō)類(lèi)Computer有個(gè)屬性printer,指定其autowire屬性為byName后,Spring IoC容器會(huì)在配置文件中查找id/name屬性為printer的bean,然后使用Setter方法為其注入。
byType:通過(guò)屬性的類(lèi)型查找JavaBean依賴(lài)的對(duì)象并為其注入。比如類(lèi)Computer有個(gè)屬性printer,類(lèi)型為Printer,那末,指定其autowire屬性為byType后,Spring IoC容器會(huì)查找Class屬性為Printer的bean,使用Setter方法為其注入。
constructor:通byType1樣,也是通過(guò)類(lèi)型查找依賴(lài)對(duì)象。與byType的區(qū)分在于它不是使用Setter方法注入,而是使用構(gòu)造子注入。
autodetect:在byType和constructor之間自動(dòng)的選擇注入方式。
default:由上級(jí)標(biāo)簽<beans>的default-autowire屬性肯定。
dependency-check
有時(shí)候某些Bean的屬性配置有毛病,這類(lèi)毛病在程序啟動(dòng)的時(shí)候不會(huì)有任何異常,會(huì)1直潛伏到Spring調(diào)用該Bean時(shí)才會(huì)被發(fā)現(xiàn)
依賴(lài)檢查能夠檢查屬性是不是被設(shè)置,如果配置了依賴(lài)檢查,程序啟動(dòng)是會(huì)進(jìn)行配置校驗(yàn),以便及時(shí)地發(fā)現(xiàn)毛病。
但是需要注意的是,依賴(lài)檢查是很僵硬的,例如設(shè)置為object,將會(huì)檢查所有的Java對(duì)象屬性,只要有1個(gè)屬性沒(méi)有設(shè)置,就會(huì)拋出異常
no或default:不做任何檢查,默許
simple:僅檢查基本類(lèi)型、集合屬性
object:僅檢查Java對(duì)象屬性
all:檢查所有屬性
Bean的高級(jí)特性
BeanNameAware接口幫助Bean知道自己在配置文件中的id
import org.springframework.beans.factory.BeanNameAware; public class BeanNameTest implements BeanNameAware{ private String beanName; //Spring會(huì)調(diào)用該方法 public void setBeanName(String beanName){ this.beanName = beanName; } }BeanFactoryAware接口幫助Bean知道哪一個(gè)BeanFactory實(shí)例化了自己
public interface BeanFactoryAware{ void setBeanFactoryAware(BeanFactory beanFactory) throws BeanException; }
用法同BeanNameAware
另外還有1下經(jīng)常使用的方法
boolean containsBean(String)判定指定名稱(chēng)的Bean是不是存在
Object getBean(String)返回指定名稱(chēng),如果沒(méi)有該Bean會(huì)拋出異常
Object getBean(String,Class)返回指定名稱(chēng)的Bean,并轉(zhuǎn)化為指定的類(lèi)對(duì)象
boolean isSingleton(String)判斷指定名稱(chēng)的Bean是不是被配置為單態(tài)模式
String []getAliases(String)返回指定名稱(chēng)的Bean的別名
InitializingBean接口會(huì)在Bean實(shí)例化后、所有屬性被設(shè)置后調(diào)用初始化方法。但是使用該接口會(huì)與Spring代碼產(chǎn)生耦合,因此不推薦使用,Spring推薦使用init-method配置
public interface InitializingBean{ public void afterPropertiesSet(); //初始化時(shí)調(diào)用此方法 }
DisposableBean接口會(huì)在Bean對(duì)象拋棄時(shí)調(diào)用燒毀方法
public interface DisposableBean{ public void destroy(); //燒毀時(shí)調(diào)用此方法 }
屬性覆蓋器
對(duì)1些參數(shù),更實(shí)用更簡(jiǎn)單的方法是使用properties配置,而不是配置在Spring的配置文件中
PropertyPlaceholderConfigurer允許把XML配置的某些參數(shù)配置到properties文件中
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc. username}"/> <property name="password" value="${jdbc. password}"/> </bean> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="loaction" value="classpath:jdbc.properties"> </bean>jdbc.properties
jdbc.driverClassName= com.mysql.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/clf?characterEncoding=UTF⑻ jdbc.username =clf jdbc.password =admin