Spring Bean

  1. Spring Bean 定義

  2. Spring Bean 做用域

  3. Spring Bean 生命週期

  4. Spring Bean 後置處理器

  5. Spring Bean 定義繼承

Spring Bean 定義

被稱做 bean 的對象是構成應用程序的支柱也是由 Spring IoC 容器管理的。bean 是一個被實例化,組裝,並經過 Spring IoC 容器所管理的對象。這些 bean 是由用容器提供的配置元數據建立的,例如,已經在先前章節看到的,在 XML 的表單中的 定義。java

bean 定義包含稱爲配置元數據的信息,下述容器也須要知道配置元數據:nginx

  • 如何建立一個 beanweb

  • bean 的生命週期的詳細信息spring

  • bean 的依賴關係

上述全部的配置元數據轉換成一組構成每一個 bean 定義的下列屬性。session

屬性 描述
class 這個屬性是強制性的,而且指定用來建立 bean 的 bean 類。
name 這個屬性指定惟一的 bean 標識符。在基於 XML 的配置元數據中,你可使用 ID 和/或 name 屬性來指定 bean 標識符。
scope 這個屬性指定由特定的 bean 定義建立的對象的做用域,它將會在 bean 做用域的章節中進行討論。
constructor-arg 它是用來注入依賴關係的,並會在接下來的章節中進行討論。
properties 它是用來注入依賴關係的,並會在接下來的章節中進行討論。
autowiring mode 它是用來注入依賴關係的,並會在接下來的章節中進行討論。
lazy-initialization mode 延遲初始化的 bean 告訴 IoC 容器在它第一次被請求時,而不是在啓動時去建立一個 bean 實例。
initialization 方法 在 bean 的全部必需的屬性被容器設置以後,調用回調方法。它將會在 bean 的生命週期章節中進行討論。
destruction 方法 當包含該 bean 的容器被銷燬時,使用回調方法。它將會在 bean 的生命週期章節中進行討論。

Bean 與 Spring 容器的關係框架

下圖表達了Bean 與 Spring 容器之間的關係:this

Spring Bean 定義

Spring 配置元數據

Spring IoC 容器徹底由實際編寫的配置元數據的格式解耦。有下面三個重要的方法把配置元數據提供給 Spring 容器:spa

  • 基於 XML 的配置文件prototype

  • 基於註解的配置code

  • 基於 Java 的配置

提示:對於基於 XML 的配置,Spring 2.0 之後使用 Schema 的格式,使得不一樣類型的配置擁有了本身的命名空間,是配置文件更具擴展性。

你已經看到了如何把基於 XML 的配置元數據提供給容器,可是讓咱們看看另外一個基於 XML 配置文件的例子,這個配置文件中有不一樣的 bean 定義,包括延遲初始化,初始化方法和銷燬方法的:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 7 
 8    <!-- A simple bean definition -->
 9    <bean id="..." class="...">
10        <!-- collaborators and configuration for this bean go here -->
11    </bean>
12 
13    <!-- A bean definition with lazy init set on -->
14    <bean id="..." class="..." lazy-init="true">
15        <!-- collaborators and configuration for this bean go here -->
16    </bean>
17 
18    <!-- A bean definition with initialization method -->
19    <bean id="..." class="..." init-method="...">
20        <!-- collaborators and configuration for this bean go here -->
21    </bean>
22 
23    <!-- A bean definition with destruction method -->
24    <bean id="..." class="..." destroy-method="...">
25        <!-- collaborators and configuration for this bean go here -->
26    </bean>
27 
28    <!-- more bean definitions go here -->
29 
30 </beans>

在上述示例中:

①xmlns="http://www.springframework.org/schema/beans",默認命名空間:它沒有空間名,用於Spring Bean的定義;

②xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance",xsi命名空間:這個命名空間用於爲每一個文檔中命名空間指定相應的Schema樣式文件,是標準組織定義的標準命名空間。

Spring Bean 做用域

Bean 的做用域

當在 Spring 中定義一個 bean 時,你必須聲明該 bean 的做用域的選項。例如,爲了強制 Spring 在每次須要時都產生一個新的 bean 實例,你應該聲明 bean 的做用域的屬性爲 prototype。同理,若是你想讓 Spring 在每次須要時都返回同一個bean實例,你應該聲明 bean 的做用域的屬性爲 singleton

Spring 框架支持如下五個做用域,分別爲singleton、prototype、request、session和global session,5種做用域說明以下所示,

注意,若是你使用 web-aware ApplicationContext 時,其中三個是可用的。    

做用域 描述
singleton

在spring IoC容器僅存在一個Bean實例,Bean以單例方式存在,默認值

prototype 每次從容器中調用Bean時,都返回一個新的實例,即每次調用getBean()時,至關於執行newXxxBean()
request 每次HTTP請求都會建立一個新的Bean,該做用域僅適用於WebApplicationContext環境
session 同一個HTTP Session共享一個Bean,不一樣Session使用不一樣的Bean,僅適用於WebApplicationContext環境
global-session 通常用於Portlet應用環境,該運用域僅適用於WebApplicationContext環境

本章將討論前兩個範圍,當咱們將討論有關 web-aware Spring ApplicationContext 時,其他三個將被討論。

singleton 做用域:

singleton 是默認的做用域,也就是說,當定義 Bean 時,若是沒有指定做用域配置項,則 Bean 的做用域被默認爲 singleton。

當一個bean的做用域爲Singleton,那麼Spring IoC容器中只會存在一個共享的bean實例,而且全部對bean的請求,只要id與該bean定義相匹配,則只會返回bean的同一實例。

也就是說,當將一個bean定義設置爲singleton做用域的時候,Spring IoC容器只會建立該bean定義的惟一實例。

Singleton是單例類型,就是在建立起容器時就同時自動建立了一個bean的對象,無論你是否使用,他都存在了,每次獲取到的對象都是同一個對象。

注意,Singleton做用域是Spring中的缺省做用域。你能夠在 bean 的配置文件中設置做用域的屬性爲 singleton,以下所示:

1 <!-- A bean definition with singleton scope -->
2 <bean id="..." class="..." scope="singleton">
3     <!-- collaborators and configuration for this bean go here -->
4 </bean>

例子

這裏是 HelloWorld.java 文件的內容:

 1 package com.tutorialspoint;
 2 public class HelloWorld {
 3    private String message;
 4    public void setMessage(String message){
 5       this.message  = message;
 6    }
 7    public void getMessage(){
 8       System.out.println("Your Message : " + message);
 9    }
10 }

下面是 MainApp.java 文件的內容:

 1 package com.tutorialspoint;
 2 import org.springframework.context.ApplicationContext;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 public class MainApp {
 5    public static void main(String[] args) {
 6       ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
 7       HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
 8       objA.setMessage("I'm object A");
 9       objA.getMessage();
10       HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
11       objB.getMessage();
12    }
13 }

下面是 singleton 做用域必需的配置文件 Beans.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 7 
 8    <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
 9       scope="singleton">
10    </bean>
11 </beans>

一旦你建立源代碼和 bean 配置文件完成後,咱們就能夠運行該應用程序。若是你的應用程序一切都正常,將輸出如下信息:

Your Message : I'm object A Your Message : I'm object A

prototype 做用域

當一個bean的做用域爲Prototype,表示一個bean定義對應多個對象實例。Prototype做用域的bean會致使在每次對該bean請求(將其注入到另外一個bean中,或者以程序的方式調用容器的getBean()方法)

時都會建立一個新的bean實例。Prototype是原型類型,它在咱們建立容器的時候並無實例化,而是當咱們獲取bean的時候纔會去建立一個對象,並且咱們每次獲取到的對象都不是同一個對象。

根據經驗,對有狀態的bean應該使用prototype做用域,而對無狀態的bean則應該使用singleton做用域。

爲了定義 prototype 做用域,你能夠在 bean 的配置文件中設置做用域的屬性爲 prototype,以下所示:

1 <!-- A bean definition with singleton scope -->
2 <bean id="..." class="..." scope="prototype">
3    <!-- collaborators and configuration for this bean go here -->
4 </bean>

例子

這裏是 HelloWorld.java 文件的內容:

 1 package com.tutorialspoint;
 2 
 3 public class HelloWorld {
 4    private String message;
 5 
 6    public void setMessage(String message){
 7       this.message  = message;
 8    }
 9 
10    public void getMessage(){
11       System.out.println("Your Message : " + message);
12    }
13 }

下面是 MainApp.java 文件的內容:

 1 package com.tutorialspoint;
 2 import org.springframework.context.ApplicationContext;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 public class MainApp {
 5    public static void main(String[] args) {
 6       ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
 7       HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
 8       objA.setMessage("I'm object A");
 9       objA.getMessage();
10       HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
11       objB.getMessage();
12    }
13 }

下面是 prototype 做用域必需的配置文件 Beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 7 
 8    <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
 9       scope="prototype">
10    </bean>
11 
12 </beans>

一旦你建立源代碼和 Bean 配置文件完成後,咱們就能夠運行該應用程序。若是你的應用程序一切都正常,將輸出如下信息:

Your Message : I'm object A Your Message : null

Spring Bean 生命週期

   理解 Spring bean 的生命週期很容易。當一個 bean 被實例化時,它可能須要執行一些初始化使它轉換成可用狀態。一樣,當 bean 再也不須要,而且從容器中移除時,可能須要作一些清除工做。

儘管還有一些在 Bean 實例化和銷燬之間發生的活動,可是本章將只討論兩個重要的生命週期回調方法,它們在 bean 的初始化和銷燬的時候是必需的。

爲了定義安裝和拆卸一個 bean,咱們只要聲明帶有 init-method 和/或 destroy-method 參數的 。init-method 屬性指定一個方法,在實例化 bean 時,當即調用該方法。一樣,destroy-method 指定一個方法,只有從容器中移除 bean 以後,才能調用該方法。

Bean的生命週期能夠表達爲:Bean的定義——Bean的初始化——Bean的使用——Bean的銷燬

初始化回調

org.springframework.beans.factory.InitializingBean 接口指定一個單一的方法:

1 void afterPropertiesSet() throws Exception;

所以,你能夠簡單地實現上述接口和初始化工做能夠在 afterPropertiesSet() 方法中執行,以下所示:

1 public class ExampleBean implements InitializingBean {
2    public void afterPropertiesSet() {
3       // do some initialization work
4    }
5 }

在基於 XML 的配置元數據的狀況下,你可使用 init-method 屬性來指定帶有 void 無參數方法的名稱。例如:

1 <bean id="exampleBean" 
2          class="examples.ExampleBean" init-method="init"/>

下面是類的定義:

1 public class ExampleBean {
2    public void init() {
3       // do some initialization work
4    }
5 }

銷燬回調

org.springframework.beans.factory.DisposableBean 接口指定一個單一的方法:

void destroy() throws Exception;

所以,你能夠簡單地實現上述接口而且結束工做能夠在 destroy() 方法中執行,以下所示:

1 public class ExampleBean implements DisposableBean {
2    public void destroy() {
3       // do some destruction work
4    }
5 }

在基於 XML 的配置元數據的狀況下,你可使用 destroy-method 屬性來指定帶有 void 無參數方法的名稱。例如:

1 <bean id="exampleBean"
2          class="examples.ExampleBean" destroy-method="destroy"/>

下面是類的定義:

1 public class ExampleBean {
2    public void destroy() {
3       // do some destruction work
4    }
5 }

若是你在非 web 應用程序環境中使用 Spring 的 IoC 容器;例如在豐富的客戶端桌面環境中;那麼在 JVM 中你要註冊關閉 hook。這樣作能夠確保正常關閉,爲了讓全部的資源都被釋放,能夠在單個 beans 上調用 destroy 方法。

建議你不要使用 InitializingBean 或者 DisposableBean 的回調方法,由於 XML 配置在命名方法上提供了極大的靈活性。

例子

咱們在適當的位置使用 Eclipse IDE,而後按照下面的步驟來建立一個 Spring 應用程序:

步驟 描述
1 建立一個名稱爲 SpringExample 的項目,而且在建立項目的 src 文件夾中建立一個包 com.tutorialspoint
2 使用 Add External JARs 選項,添加所需的 Spring 庫,解釋見 Spring Hello World Example 章節。
3 在 com.tutorialspoint 包中建立 Java 類 HelloWorld 和 MainApp
4 在 src 文件夾中建立 Beans 配置文件 Beans.xml
5 最後一步是建立的全部 Java 文件和 Bean 配置文件的內容,並運行應用程序,解釋以下所示。

這裏是 HelloWorld.java 的文件的內容:

 1 package com.tutorialspoint;
 2 
 3 public class HelloWorld {
 4    private String message;
 5 
 6    public void setMessage(String message){
 7       this.message  = message;
 8    }
 9    public void getMessage(){
10       System.out.println("Your Message : " + message);
11    }
12    public void init(){
13       System.out.println("Bean is going through init.");
14    }
15    public void destroy(){
16       System.out.println("Bean will destroy now.");
17    }
18 }

下面是 MainApp.java 文件的內容。在這裏,你須要註冊一個在 AbstractApplicationContext 類中聲明的關閉 hook 的 registerShutdownHook() 方法。它將確保正常關閉,而且調用相關的 destroy 方法。

 1 package com.tutorialspoint;
 2 import org.springframework.context.support.AbstractApplicationContext;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 public class MainApp {
 5    public static void main(String[] args) {
 6       AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
 7       HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
 8       obj.getMessage();
 9       context.registerShutdownHook();
10    }
11 }

 

下面是 init 和 destroy 方法必需的配置文件 Beans.xml 文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 7 
 8    <bean id="helloWorld" 
 9        class="com.tutorialspoint.HelloWorld"
10        init-method="init" destroy-method="destroy">
11        <property name="message" value="Hello World!"/>
12    </bean>
13 </beans>

一旦你建立源代碼和 bean 配置文件完成後,咱們就能夠運行該應用程序。若是你的應用程序一切都正常,將輸出如下信息:

Bean is going through init. Your Message : Hello World! Bean will destroy now.

默認的初始化和銷燬方法

若是你有太多具備相同名稱的初始化或者銷燬方法的 Bean,那麼你不須要在每個 bean 上聲明初始化方法銷燬方法。框架使用 元素中的 default-init-method 和 default-destroy-method 屬性提供了靈活地配置這種狀況,以下所示:

 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://www.springframework.org/schema/beans
 4     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
 5     default-init-method="init" 
 6     default-destroy-method="destroy">
 7 
 8    <bean id="..." class="...">
 9        <!-- collaborators and configuration for this bean go here -->
10    </bean>
11 
12 </beans>

Spring Bean 後置處理器

 

Spring Bean 定義繼承

相關文章
相關標籤/搜索