Spring--容器和bean

Spring 容器是 Spring 框架的核心。容器建立對象,把它們鏈接在一塊兒,配置它們,並管理他們的整個生命週期,從建立到銷燬。Spring 容器使用依賴注入(DI)來管理組成一個應用程序的組件。這些對象被稱爲 Spring Beans。java

配置bean能夠經過 XML,也能夠經過Java 註釋或 Java 代碼來實現。web

下圖是 Spring 如何工做的高級視圖。 Spring IoC 容器利用 Java 的 POJO 類和配置元數據來生成徹底配置和可執行的系統或應用程序。spring

Sping 的 BeanFactory 容器

這是一個最簡單的容器,它主要的功能是爲依賴注入 (DI) 提供支持,這個容器接口在 org.springframework.beans.factory.BeanFactor 中被定義。session

在 Spring 中,有大量對 BeanFactory 接口的實現。其中,最常被使用的是 XmlBeanFactory 類。這個容器從一個 XML 文件中讀取配置元數據,由這些元數據來生成一個被配置化的系統或者應用。app

在資源寶貴的移動設備或者基於 applet 的應用當中, BeanFactory 會被優先選擇。不然,通常使用的是 ApplicationContext,除非你有更好的理由選擇 BeanFactory。框架

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
        HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
        obj.getMessage();

Sping 的ApplicationContext容器*

Application Context 是 spring 中較高級的容器。和 BeanFactory 相似,它能夠加載配置文件中定義的 bean。 另外,它增長了企業所須要的功能,好比,從屬性文件中解析文本信息和將事件傳遞給所指定的監聽器。ApplicationContext 包含 BeanFactory 全部的功能,通常狀況下,相對於 BeanFactory,ApplicationContext 會更加優秀。固然,BeanFactory 仍能夠在輕量級應用中使用,好比移動設備或者基於 applet 的應用程序。post

最常被使用的 ApplicationContext 接口實現:測試

  • FileSystemXmlApplicationContext:該容器從 XML 文件中加載bean。在這裏,你須要提供給構造器 XML 文件的完整路徑。
ApplicationContext context = new FileSystemXmlApplicationContext

            ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");

        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

        obj.getMessage();
  • ClassPathXmlApplicationContext:該容器從 XML 文件中加載 bean。不須要提供 XML 文件的完整路徑,只需正確配置 CLASSPATH 環境變量便可,容器會從 CLASSPATH 中搜索 bean 配置文件。
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        obj.getMessage();
  • WebXmlApplicationContext:該容器會在一個 web 應用程序的範圍內加載在 XML 文件中已被定義的 bean。

Bean的定義

被稱做 bean 的對象是構成應用程序的支柱也是由 Spring IoC 容器管理的。spa

 

Bean的常見屬性code

Id/_Name(不可重複) 這個屬性指定惟一的 bean 標識符。在基於 XML 的配置元數據中,你可使用 ID 和/或 name 屬性來指定 bean 標識符
Class 這個屬性是強制性的,而且指定用來建立 那個類的 bean 類
Scope  這個屬性指定由特定的 bean 定義建立的對象的做用域(默認Singleton)
Constructor-arg 使用構造方法注入依賴關係的
Properties 使用setter方法注入依賴
Autuwire  自動匹配並注入依賴(默認爲no,不自動匹配) 
Lazy-init 告訴容器延遲初始化bean,制動請求才建立(默認值false,容器建立自動建立對象)
Init-method 在實例化 bean 時,當即調用該方法
Destroy-method 從容器中移除 bean 以後,調用該方法

Bean的做用域scope屬性(默認值singleton)

Singleton ioc容器中只存在一個bean實例,bean以單例存在
Prototype 每次從容器請求bean是,都會建立一個新的bean對象
Request 每次http請求都會建立一個新的bean對象
Session 同一個http session共享一個bean
global-session 通常用於Portlet應用環境

Bean的生命週期

當一個 bean 被實例化時,它可能須要執行一些初始化使它轉換成可用狀態。一樣,當 bean 再也不須要,而且從容器中移除時,可能須要作一些清除工做。init-method 屬性指定一個方法,在實例化 bean 時,當即調用該方法。一樣,destroy-method 指定一個方法,只有從容器中移除 bean 以後,才能調用該方法。

只要聲明帶有 init-method 和/或 destroy-method 參數的 :

<bean id="helloWorld" class="com.tutorialspoint.HelloWorld" init-method="init" destroy-method="destroy">
    <property  name="message" value="Hello World!"/> 
    </bean>

若是想要測試調用destroy-method方法,須要調用在 AbstractApplicationContext 類中聲明的關閉 hook 的 registerShutdownHook() 方法。它將確保正常關閉,而且調用相關的 destroy 方法。

AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        obj.getMessage();
        context.registerShutdownHook();

生命週期回調方法

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

實現兩個接口,並重寫方法,代替了xml中配置init-method和destroy-method元素

初始化回調

public class ExampleBean implements InitializingBean {
   public void afterPropertiesSet() {
      // do some initialization work
   }
}

銷燬回調

public class ExampleBean implements DisposableBean {
   public void destroy() {
      // do some destruction work
   }
}

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

默認的初始化和銷燬方法

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

Spring - Bean後置處理器

BeanPostProcessor接口定義回調方法,你能夠實現該方法來提供本身的實例化邏輯,依賴解析邏輯等。

任何bean的初始化的以前和以後輸入該bean的名稱。在初始化bean的以前和以後實現更復雜的邏輯

public class InitHelloWorld implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeforeInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("AfterInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
}

註冊接口的實現類

<bean id="helloWorld" class="com.tutorialspoint.HelloWorld"
       init-method="init" destroy-method="destroy">
       <property name="message" value="Hello World!"/>
   </bean>
   <!-- 註冊接口的實現類-->
   <bean class="com.tutorialspoint.InitHelloWorld" />

Spring Bean 定義繼承

子 bean 的定義繼承父定義的配置數據。子定義能夠根據須要重寫一些值,或者添加其餘值。

Bean 定義模板

你能夠建立一個 Bean 定義模板,不須要花太多功夫它就能夠被其餘子 bean 定義使用。在定義一個 Bean 定義模板時,不指定類的屬性,而應該指定帶 true 值的抽象屬性,以下所示:

<bean id="beanTeamplate" abstract="true">
      <property name="message1" value="Hello World!"/>
      <property name="message2" value="Hello Second World!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

   <bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate">
      <property name="message1" value="Hello India!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

父 bean 自身不能被實例化,由於它是不完整的,並且它也被明確地標記爲抽象的。當一個定義是抽象的,它僅僅做爲一個純粹的模板 bean 定義來使用的,充當子定義的父定義使用。

相關文章
相關標籤/搜索