目錄
- 實例化Bean的方式
- 使用構造函數實例化Bean
- 使用靜態工廠的方式實例化Bean
- 使用實例化工廠方式實例化Bean
- 通過實現FactoryBean自定義實例化Bean
實例化Bean的方式
- bean的創建本質上就是創建一個或多個具有外部配置屬性的對象,容器在啟動的時候會查看命名Bean的配置屬性,并使用該Bean Definition封裝的配置來創建或獲取一個對象。
- Spring提供了利用容器本身通過反射方式調用構造函數直接創建Bean的方式
- 同時也提供了調用靜態工廠的方式創建Bean(
需制定要被調用的靜態工廠方法的實際類
)
如果是在Bean中定義了一個靜態嵌套類, 比如在com.example中有一個叫做Dog的類,在Dog里有一個叫做OurDog的靜態嵌套類,在Bean中的定義可以是
class=com.example.Dog$OurDog或者com.example.Dog.OurDog
使用構造函數實例化Bean
- 使用構造函數實例化如果沒有任何構造方法的依賴注入,僅僅只需要一個默認為空的構造函數即可,這種方式使得所有普通類都可以被Spring兼容
<bean id="xmlBean" class="com.nobugnolife.bean.impl.XmlBeanImpl"/>
- 有參構造函數會在我之后的文章中進行描述。
使用靜態工廠的方式實例化Bean
- 定義一個靜態方法創建Bean需要使用class指定包含靜態工廠方法的類,并通過factory-method提供需要調用的方法,之后便會通過方法調用對象的構造函數創建并返回。
- 靜態工廠類
public class StaticBeanFactory {private static ClientBean clientBean = new ClientBeanImpl();private StaticBeanFactory() {}public static ClientBean createInstance() {return clientBean;}
}
- xml配置
<!-- 使用靜態工廠方式實例化bean--><!-- class提供靜態工廠的類路徑--><!-- factory-method選擇創建對應Bean的對象方法 --><bean id="clientBean" class="com.nobugnolife.factory.StaticBeanFactory" factory-method="createInstance"/>
使用實例化工廠方式實例化Bean
- 和靜態工廠方法類似,不過實例化工廠需要先從容器中調用工廠Bean本身的方法來創建Bean,我們需要提供factory-bean屬性來關聯指定創建Bean對象的工廠Bean,并通過factory-method設置調用方法創建對象。
值的注意的是,靜態工廠和實例化工廠在bean的屬性中都不需要提供指定Bean的class屬性,而轉為提供對應工廠Bean的class,因為工廠的方法本身就已經和對應的Bean進行了關聯
- 需要先創建一個工廠類
public class SampleBeanFactory {private static SampleBean sampleBean = new SampleBeanImpl();public SampleBean createSampleBeanInstance(){return sampleBean;}
}
- 配置xml
<!-- 使用工廠方式實例化bean --><!-- 首先需要將工廠類配置到bean中 --><bean id="sampleBeanFactory" class="com.nobugnolife.factory.SampleBeanFactory"/><!-- 通過factory-bean將工廠bean綁定 --><bean id="sampleBean" factory-bean="sampleBeanFactory" factory-method="createSampleBeanInstance"/>
- 抽象工廠的原理和工廠類似,不過在Spring框架中提供了一個FactoryBean接口,那些本身就是工廠的對象實現 org.springframework.beans.factory.FactoryBean 接口,可以簡化實例化工廠的配置。
通過實現FactoryBean自定義實例化Bean
- Spring框架本身提供了FactoryBean接口,允許讓本就是工廠的類實現此接口,從而簡化XML的表達
- FactoryBean 接口提供三個方法:
- T getObject():返回本工廠創建的對象的一個實例。該實例可能會被共享,這取決于該工廠是返回singleton還是prototype
- boolean isSingleton():如果這個FactoryBean返回的Bean是singleton,則返回true,否則返回false。默認返回true
- Class<?> getObjectType():返回由getObject()方法返回的對象類型,如果事先不知道類型,則返回null
Spring框架大量使用FactoryBean接口,在ApplicantContext相關的實現類中以及其他很多地方都能看到FactoryBean的接口實現類,官方文檔的描述中Spring本身就有50多個FactoryBean的接口實現。
- 值得注意的是在調用 ApplicationContext的getBean()方法時,在Bean的id前加(&)會返回 FactoryBean實例本身。
- 創建工廠類并實現FactoryBean接口
public class ImplBeanFactory implements FactoryBean<ImplBean> {@Overridepublic ImplBean getObject() throws Exception {// 這里直接創建實現類對象并返回return new ImplBeanImpl();}@Overridepublic Class<?> getObjectType() {// 返回的是Class類型return ImplBean.class;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}
- 配置xml
<!-- 繼承FactoryBean接口的工廠會被Spring自動創建到容器中就無需配置工廠bean -->
<!-- 因為是實現的spring規范接口,所以無需提供factory-method,spring會自動調用getObject方法 -->
<bean id="implBean" class="com.nobugnolife.factory.ImplBeanFactory"/>