Bean的配置一共有兩種方式:一種是基於XML文件的方式,另外一種是基於註解的方式。
本文主要介紹基於XML文件的方式html
<bean id="helloWorld" class="com.sevenhu.domain.HelloWorld"> <property name="userName" value="Spring"></property> </bean>
上面的配置代碼中:
id:Bean的名稱,在IOC容器中必須是惟一的,若id,沒有指定,那麼Spring自動將類名做爲Bean的名字,id能夠指定多個名字,名字之間可用逗號,分 號,或空格分隔。
Spring容器
在Spring IOC容器讀取Bean配置建立Bean實例以前,必須對它進行實例化,只有在容器實例化以後,才能夠從IOC容器裏獲取Bean的實例並使用。
Spring提供了兩種類型的IOC容器實現
-BeanFactory:Ioc容器的基本實現。
-ApplicationContext:提供了更多的高級特性。是BeanFactory的子接口。
-BeanFactory是Spring框架的基礎設施,面向Spring自己;ApplicationContext面向使用Spring框架的開發者。
ApplicationContext主要有兩個實現類:
-ClassPathXmlApplicationContext:從類路徑下加載配置文件。
-FileSystemXmlApplicationContext:從文件系統中加載配置文件。
ApplicationContext在初始化上下文時就實例化全部單例的bean。
屬性注入:
即經過setter方法注入bean的屬性值或依賴的對象。屬性注入使用<property>元素,使用name屬性值指定bean的屬性名稱,value屬性指定屬性值。使用這種注入方式,那麼bean中必須有一個默認的構造函數,即無參的構造函數。
java
eg: <property name="userName" value="Spring"></property>
構造方法注入:
按索引匹配入參:mysql
<bean id="car" class="com.sevenhu.domain.Car"> <constructor-arg value="長春一汽" index="0"></constructor-arg> <constructor-arg value="2000" index="1"></constructor-arg> <constructor-arg value="奧迪" index="2"></constructor-arg> </bean>
按類型匹配入參:spring
<bean id="car2" class="com.sevenhu.domain.Car"> <constructor-arg value="長春一汽" type="java.lang.String"></constructor-arg> <constructor-arg value="2000" type="double"></constructor-arg> <constructor-arg value="奧迪" type="java.lang.String"></constructor-arg> </bean>
注:字面值均可用字符串表示,能夠經過<value>元素標籤或value屬性進行注入。基本數據類型及其封裝類,String等類型均可以採用字面值注入的方 式。
若是一個bean的某一個屬性是一個對象,可以使用以下配置:sql
<bean id="people" class="com.sevenhu.domain.People"> <property name="name" value="hujingwei"></property> <property name="car" ref="car2"></property> </bean>
或者使用內部類:session
<bean id="people1" class="com.sevenhu.domain.People"> <property name="name" value="zhangsongzhu"></property> <property name="car"> <!--內部bean,不能被外部的bean所引用,所以沒有必要設置id--> <bean class="com.sevenhu.domain.Car"> <property name="brand" value="Ford"></property> <property name="creator" value="SomeOne"></property> <property name="price" value="100000"></property> </bean> </property> </bean>
可使用專用的<null/>元素標籤爲Bean的字符串或其它對象的屬性值注入null值,以下:app
<bean id="people2" class="com.sevenhu.domain.People"> <property name="name" value="hu"></property> <!--若某一個bean的屬性值須要設置爲null--> <property name="car"><null/></property> </bean>
使用p命名空間:框架
爲了簡化XML文件的配置,愈來愈多的XML文件使用屬性而非子元素配置信息,所以Spring自從2.5以後就引入了一個p命名空間,能夠經過<bean>元素屬性的方式配置Bean的屬性dom
<!--使用p命名空間--> <bean id="people3" class="com.sevenhu.domain.People" p:name="seven" p:car-ref="car1"> </bean>
XML配置裏的Bean自動裝配ide
Spring IOC容器能夠自動裝配bean,須要作的僅僅是在<bean>的autowire屬性中指定自動裝配的模式,具體的裝配模式以下:
-byType(根據類型裝配):若IOC容器中有多個與目標bean類型一致的bean,在這種狀況下,Spring將沒法斷定哪一個bean最適合該屬性,因此不能進行自動裝配。
-byName(根據名稱自動裝配):必須將目標bean的名稱和屬性名設置的徹底相同。
自動裝配的缺點:在bean配置文件裏設置autowire屬性進行自動裝配將會裝配bean的全部屬性,然而,若只但願裝配個別屬性,autowire不夠靈活;autowire屬性要麼根據類型裝配,要麼根據名稱裝配,不能二者兼而有之。
繼承bean配置
Spring容許繼承bean的配置,被繼承的bean稱爲父bean,繼承這個bean的bean爲子bean。子bean從父bean中繼承配置,包括bean的屬性配置,子bean也能夠覆蓋從父bean繼承過來的配置,父bean能夠做爲配置模版,也能夠做爲bean實例,若指向把父bean做爲模版,能夠設置bean的abstract屬性爲true,這樣Spring就不會實例化這個bean。並非父bean中全部的屬性都會被繼承,好比:autowire,abstract等;也能夠忽略父bean的class屬性,讓子bean指定本身的類,而共享相同的屬性配置,可是此時abstract必須設爲true。
<bean id="user" class="com.*.*"> <property name="userName" value="hu"/> </bean> <bean id="user1" parent="user"> <property name="userName" value="hu"/> </bean> <bean id="user2" parent="user"> <property name="userName" value="hu"/> </bean>
依賴bean配置:
Spring容許用戶經過depends-on屬性設定bean前置依賴的bean,前置依賴的bean會在bean實例化以前建立好,若是前置依賴多個bean,則能夠經過逗號,空格的方式配置bean的名稱。
<bean id="user3" depends-on="user1"> </bean>
bean的做用域(經過<bean>標籤的scope屬性設置)
-singleton 在Spring IOC容器中只存在一個bean實例,bean以單例的方式存在(默認的做用域)
-prototype 每次調用getBean()時都會返回一個新的實例
-request 每次HTTP請求都會返回一個新的bean,該做用域僅適用於WebApplicationContext環境中
-session 在session中共享一個bean,該做用域僅適用於WebApplicationContext環境中
使用外部屬性文件:
首先外部文件db.properties的內容以下:
jdbc.user=root jdbc.password=1230 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql:///test jdbc.initPoolSize=5 jdbc.maxPoolSize=10
那麼在配置文件中配置以下:
<!-- 導入外部的資源文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean>
IOC容器中Bean的生命週期
-經過構造器或工廠方法建立bean實例
-爲bean的屬性設置值和對其它bean的引用
-調用bean的初始化方法
-bean可使用了
-當容器關閉的時候,調用bean的銷燬方法。
注:當bean的聲明裏設置init-method和destroy-method屬性,爲bean指定初始化和銷燬方法(這兩個方法通常都沒有參數)
建立bean的後置處理器
bean後置處理器容許在調用初始化方法先後對bean進行額外的處理,bean後置處理器對IOC容器裏全部bean實例逐一處理,而非單一實例。對bean的後置處理器而言,須要實現
Interface BeanPostProcessor接口,在初始化方法被調用先後,Spring將把每一個bean實例分別傳遞給BeanPostProcessor接口的如下兩個方法:
postProcessorAfterInitialization(Object bean,String beanName); postProcessorBeforeInitialization(Object bean,String beanName);
添加後置處理器後Bean的生命週期
-經過構造器或工廠方法建立bean實例
-爲bean的屬性設置值和對其它bean的引用
-將bean實例傳遞給後置處理器的postProcessorBeforeInitialization(Object bean,String beanName);方法
-調用bean的初始化方法
-將bean實例傳遞給後置處理器的postProcessorAfterInitialization(Object bean,String beanName);方法
-bean可使用了
-當容器關閉的時候,調用bean的銷燬方法。
代碼以下:
package com.sevenhu.domain; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by hu on 2016/4/1. */ public class MyBean implements BeanPostProcessor { //該方法在bean的初始化方法以前調用 @Override public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { //o就是bean實例對象,s就是bean實例的id System.out.println("before initialication ...."); //返回bean的實例對象 return o; } //該方法在bean的初始化方法以後調用 @Override public Object postProcessAfterInitialization(Object o, String s) throws BeansException { System.out.println("after initialication ...."); return o; } public static void main(String[] args){ ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml"); } }
配置代碼以下:
<!--配置bean後置處理器:不須要配置id屬性,IOC容器會識別到它是一個bean後置處理器,並調用其方法--> <bean class="com.sevenhu.domain.MyBean"></bean>
經過調用靜態工廠方法建立bean
調用靜態工廠方法建立bean是將對象建立的過程封裝到靜態方法中,當客戶端須要對象時,只須要簡單地調用靜態方法,而不關心建立對象的細節。
直接上代碼,工廠以下:
<!-- 經過工廠方法的方式來配置 bean --> <!-- 1. 經過靜態工廠方法: 一個類中有一個靜態方法, 能夠返回一個類的實例(瞭解) --> <!-- 在 class 中指定靜態工廠方法的全類名, 在 factory-method 中指定靜態工廠方法的方法名 --> <bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance"> <!-- 能夠經過 constructor-arg 子節點爲靜態工廠方法指定參數 --> <constructor-arg value="2"></constructor-arg> </bean> <!-- 2. 實例工廠方法: 先須要建立工廠對象, 再調用工廠的非靜態方法返回實例(瞭解) --> <!-- ①. 建立工廠對應的 bean --> <bean id="simpleDateFormat" class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg> </bean> <!-- ②. 有實例工廠方法來建立 bean 實例 --> <!-- factory-bean 指向工廠 bean, factory-method 指定工廠方法(瞭解) --> <bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse"> <!-- 經過 constructor-arg 執行調用工廠方法須要傳入的參數 --> <constructor-arg value="1990-12-12 12:12:12"></constructor-arg> </bean>