一個Bean的定義本質上是能創建一個或者更多Bean的設計圖(如何創建Bean的設計說明書)。當容器收到請求時查看指定Bean的說明書,然后通過此說明書創建或者獲取真實的對象。
如果使用基于XML的配置元數據,在`<bean/>`元素的`class`屬性中指定對象的類型用于實例化。`class`屬性對應與`BeanDefinition`對象中`beanClass`成員變量,這通常是必須的(一些例外的情況請參見:下文的通過工廠方法實例化Bean和[1.7.繼承Bean定義](1.7.繼承Bean定義.md))。
`class`屬性被用于下面的兩種情況之一。
* 一般地,容器可以直接通過class反射調用構造器來創建對象,相當于在Java代碼中使用`new`操作符。
* 指定的class中包含創建對象的工廠方法,這種方式是不常見的。工廠方法返回的對象可能可class的類型一致,也可能完全不一致。
> ##### 內部類類名
> 如果你想配置一個靜態內部類的Bean定義,你必須使用二進制的類名。
>
> 比如:在`com.example`包內有一個名為`Foo`的類,在這個類中包含一個名為`Bar`的靜態內部類,在`class`屬性中你可以這么來指定:`com.example.Foo$Bar`
>
> 注意:'$'符號用于分隔外部和內部類。
* * * * *
### **通過構造器實例化**
當通過構造器來創建對象時,簡單普通的類在Spring中都是可用的,兼容性良好的。換而言之,Spring實例化的對象不需要實現任何接口或者編寫特定的代碼,只需要提供類名即可。無論如何,根據指定Bean使用的IOC類型,你可能需要一個無參構造器。
Spring可以管理任何類型的Bean,不僅僅是JavaBean。大多數開發者更喜歡帶有無參構造和Getter、Setter方法的JavaBean。容器也可以管理非Bean風格的類,比如和JavaBean規范無關的連接池。
在基于XML的配置元數據中,你可以通過下面的樣例來指定Bean的配置。
~~~
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
~~~
關于提供參數給構造器以及在創建對象后為其設置屬性的詳細信息請參見:[1.4.1.依賴注入](1.4.1.依賴注入.md)。
* * * * *
### **通過靜態工廠方法實例化**
如果你想通過靜態工廠方法來創建對象,可以在`class`屬性中指定包含靜態工廠方法的類并在`factory-method`屬性中指定此類的工廠方法。這種創建對象的方式主要用于遺留的代碼中。
在下面的Bean定義中,對象會被指定的工廠方法來創建。只需一個包含工廠方法的類即可,無需指定返回對象的類型。在這個例子中,`createInstance()`必須是靜態方法。
~~~
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
~~~
~~~
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
~~~
關于提供參數給工廠方法以及在工廠方法創建對象后設置屬性的詳細信息請參見:[1.4.2.依賴配置詳情](1.4.2.依賴配置詳情.md)。
* * * * *
### **通過實例工廠方法實例化**
和靜態工廠方法實例化對象類似,對象可以通過容器中已存在的Bean(工廠Bean)來創建,該Bean包含一個非靜態的工廠方法。要使用這種方式來創建對象,首先在`factory-bean`屬性中指定上述提到的工廠Bean,然后在`factory-method`屬性中指定工廠方法。
~~~
<!-- 包含創建對象的工廠Bean-->
<bean id="serviceLocator" class="examples.DefaultServiceLocator"/>
<!-- 此Bean的創建通過指定的工廠Bean -->
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
~~~
~~~
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
~~~
一個工廠類可以包含多個工廠方法,如下所示:
~~~
<bean id="serviceLocator" class="examples.DefaultServiceLocator"/>
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
<bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>
~~~
~~~
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
private static AccountService accountService = new AccountServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
public AccountService createAccountServiceInstance() {
return accountService;
}
}
~~~
從上例可以看出:通過依賴注入可以配置和管理工廠Bean,詳情參見:[1.4.2.依賴和配置詳情](1.4.2.依賴和配置詳情.md)。
> 在Spring 文檔中,工廠Bean是通過上述方法來創建對象的Bean。而`FactoryBean`是構成Spring相關的Bean。
- ---- 閱讀說明
- 一、核心技術
- 1.IOC容器
- 1.1.IOC 容器和 Bean 簡介
- 1.2.容器概覽
- 1.2.1.配置元數據
- 1.2.2.實例化容器
- 1.2.3.使用容器
- 1.3.Bean概覽
- 1.3.1.Bean的命名
- 1.3.2.實例化Bean
- 1.4.依賴
- 1.4.1.依賴注入
- 1.4.2.依賴配置詳情
- 1.4.5.注入合作者
- 1.4.4.Bean的懶加載
- 1.5.Bean的范圍
- 1.6.自定義Bean的特性
- 1.6.1.生命周期回調函數
- 1.7.繼承Bean定義
- 1.9.基于注解的容器配置
- 1.9.1.@Required
- 1.12.基于Java的容器配置
- 1.12.3.使用@Bean注解
- 1.15.ApplicationContext的附加功能
- 1.15.4.Web 應用中便捷的 ApplicationContext 實例
- 1.16.BeanFactory
- 2.資源
- 2.7.應用上下文和資源路徑
- 3.驗證、數據綁定以及類型轉換
- 3.5.Spring類型轉換
- 3.5.4.ConversionService API
- 5.基于 Spring 的面向切面編程
- 5.8.在 Spring 中使用 AspectJ
- 5.8.1.在 Spring 中使用 AspectJ 注入領域對象
- 二、測試
- 三、數據訪問
- 四、Web應用
- 五、Web響應式編程
- 六、集成
- 4.1.介紹
- 七、編程語言