天天看點

spring-framework (Version 5.2.9.RELEASE)-核心技術 bean

Bean 概覽

一個 Spring IoC 視窗中管理着一個或者多個bean。這些bean根據我們提供的配置給視窗進行建立(如:xml中 的定義 )
在容器中,bean的定義是用 BeanDefinition 來表示,它包含以下的資訊:
  1. 通過包來限定類名:通常,是用實作類來定義bean。
  2. Bean 行為配置的元素,它的狀态展現在容器中(範圍,生命周期的回調,等等)
  3. 一個bean要工作需要依賴其它bean。這種依賴關系我們叫作協作或者依賴。
  4. 其他配置,在建立對象之前 ,如:容器大小的限制,或者管理連接配接池bean連接配接數的限制。
中繼資料通過一系列屬性标記定義。如下 :
Property Explained in…
Class Instantiating Beans
Name Naming Beans
Scope Bean Scopes
Constructor arguments Dependency Injection]
Properties Dependency Injection
Autowiring mode Autowiring Collaborators
Lazy initialization mode [Lazy-initialized Beans
Initialization method Initialization Callbacks
Destruction method Destruction Callbacks

執行個體化bean

一個bean的定義本質上可以用來建立一個或者多個對象。容器裡查找配置當一個命名的bean被請求或者使用使用中繼資料進行封閉建立一個實際對象。
如果你是使用XML作為基礎的配置,應該指定對象的類型用來執行個體化在 元素的class 屬性。這個 class 屬性( BeanDefinition 執行個體的 Class 屬性)通常是強制的。(對于例外的情況:see Instantiation by Using an Instance Factory Method and Bean Definition Inheritance)使用 Class 屬性的兩種方式之一:
通常,指定bean class 在例子的構造,容器通過構造器方法反射建立bean,和java代碼中使用 new 進行操作一樣。
指定實體類包含 static 工廠方法,執行這個工廠方法建立對象,不常用的情況下,容器會執行一個 static 工廠方法基于class建立bean。這個對象的類型 static 工廠方法傳回的類型可以是同一個類或者完全另外一個類。
  • 内部類命名
如果你配置的一個bean定義裡面包含一個靜态内部類,應該使用位元組名命名内部類。
例如,有一個類叫SomeThing 在 com.example 這個包下,并且 SomeThing 這個類含有一個靜态内部類叫 OtherThing, 在bean定義下 class 屬性應該寫成 com.example.SomeThing$OtherThing.
注意 使用 $ 字元來把外部類名和内部類名分隔開來。
  • 使用構造器進行執行個體化。
使用構造器方法建立bean時,所有通常的類都可以使用并且和Spring 相容。即,類的開發不需要實作任何指定的接口或者指定的一種方式。簡單的指定bean的class就足夠。但是,Ioc容器指定bean的類型之後 ,有可能一個預設的空的構造方法。
Spring IoC容器實際上可以模拟管理所有的class你要它的管理類。它不限制于管理是真的JavaBean。大多數 Spring 使用者更喜歡使用一個預設的空的構造方法和适當的 setter 和 getter 方法在容器上進行模組化。在容器也有許多非bean風格的class。例如,如果你需要一個不符合javaBean規範的的連接配接池,Spring 也可以很好的管理。
使用xml進行配置,可以使用 bean的class 如下:
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
           
  • 使用靜态工廠方法進行執行個體化
當要定義一個bean時也可以使用靜态的工廠方法,使用 class 屬性指定bean 的class 其中包容一個靜态的工廠方法使用 factory-method 屬性來指定工廠方法的名稱。這個方法是要可以被指定的(帶有可選的參數,在後面會進行描述)并且傳回一個對象,它就相當是通過構造器方法進行建立的。這種建立方法,就是把bean定義建立放在靜态工廠方法中。
下面bean的定義就是使用一個工廠方法進行建立的。這種聲明方法不用聲明傳回對象的類型,這個類型包含在工廠方法。這個例子 , createInstance() 必須使用一個靜态方法。下面例子展示如何使用工廠方法建立聲明建立bean。
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>
           
例子中,bean定義中指定class 的代碼如下 :
public class ClientService {

private static ClientService clientService = new ClientService();

private ClientService() {}


public static ClientService createInstance() {
return clientService;
}
}
           
  • 使用一個執行個體化一個工廠方法執行個體化bean。
和使用 靜态工廠方法一樣,使用一個執行個體化工廠類執行一個非靜态方法從容器中建立一個存在的bean。使用這個機制, class 屬性可以是為空的,在 factory-bean 屬性,指定目前容器中含有一個執行個體化方法用它來建立對象的bean的名稱。如下:
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean --></bean>

<!-- the bean to be created via the factory bean -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
           
例子中互相互動class内容:
public class DefaultServiceLocator {

private static ClientService clientService = new ClientServiceImpl();

public ClientService createClientServiceInstance() {
return clientService;
}
}
           
一個工廠類可以有一個或者多個工廠方法,如下:
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean --></bean>

<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>

<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
           
例子中,class的代碼如下 :
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;
}
}