Spring 容器是 Spring 框架的核心。容器建立對象,把它們鏈接在一塊兒,配置它們,並管理他們的整個生命週期,從建立到銷燬。Spring 容器使用依賴注入(DI)來管理組成一個應用程序的組件。這些對象被稱爲 Spring Beans。java
配置bean能夠經過 XML,也能夠經過Java 註釋或 Java 代碼來實現。web
下圖是 Spring 如何工做的高級視圖。 Spring IoC 容器利用 Java 的 POJO 類和配置元數據來生成徹底配置和可執行的系統或應用程序。spring
這是一個最簡單的容器,它主要的功能是爲依賴注入 (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();
Application Context 是 spring 中較高級的容器。和 BeanFactory 相似,它能夠加載配置文件中定義的 bean。 另外,它增長了企業所須要的功能,好比,從屬性文件中解析文本信息和將事件傳遞給所指定的監聽器。ApplicationContext 包含 BeanFactory 全部的功能,通常狀況下,相對於 BeanFactory,ApplicationContext 會更加優秀。固然,BeanFactory 仍能夠在輕量級應用中使用,好比移動設備或者基於 applet 的應用程序。post
最常被使用的 ApplicationContext 接口實現:測試
ApplicationContext context = new FileSystemXmlApplicationContext ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage();
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage();
被稱做 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 再也不須要,而且從容器中移除時,可能須要作一些清除工做。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-method 和 default-destroy-method 屬性提供了靈活地配置這種狀況
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" />
子 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 定義來使用的,充當子定義的父定義使用。