配置 bean
–配置形式:基於 XML 文件的方式;基於註解的方式
–Bean 的配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法 & 實例工廠方法)、FactoryBean
–IOC 容器 BeanFactory & ApplicationContext概述
–依賴注入的方式:屬性注入;構造器注入
–自動轉配 : auto屬性,會自動給剩下的所有屬性賦值
–bean 之間的關係:parent和depends-on
–bean 的作用域:singleton;prototype;WEB 環境作用域
–使用外部屬性文件
–spEL
–IOC 容器中 Bean 的生命週期
–Spring 4.x 新特性:泛型依賴注入
IOC(Inversion of Control):其思想是反轉資源獲取的方向. 傳統的資源查找方式要求組件向容器發起請求查找資源. 作爲迴應, 容器適時的返回資源. 而應用了IOC 之後, 則是容器主動地將資源推送給它所管理的組件, 組件所要做的僅是選擇一種合適的方式來接受資源. 這種行爲也被稱爲查找的被動形式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 配置一個 bean 一個bean標籤代表給容器添加了一個對象.class用全類名錶示通過反射方式實例化對象,所以類中需要一個無參的構造函數,--> <bean id="helloWorld" class="com.atguigu.spring.helloworld.HelloWorld"> <!-- 爲屬性賦值 --> <property name="user" value="Jerry"></property> </bean> <!-- 配置一個 bean --> <bean id="helloWorld2" class="com.atguigu.spring.helloworld.HelloWorld"> <!-- 爲屬性賦值 --> <!-- 通過屬性注入: 通過 setter 方法注入屬性值 --> <property name="user" value="Tom"></property> </bean> <!-- 通過構造器注入屬性值 --> <bean id="helloWorld3" class="com.atguigu.spring.helloworld.HelloWorld"> <!-- 要求: 在 Bean 中必須有對應的構造器. --> <constructor-arg value="Mike"></constructor-arg> </bean> <!-- 若一個 bean 有多個構造器, 如何通過構造器來爲 bean 的屬性賦值 --> <!-- 可以根據 index 和 value 進行更加精確的定位. (瞭解) --> <bean id="car" class="com.atguigu.spring.helloworld.Car"> <constructor-arg value="KUGA" index="1"></constructor-arg> <constructor-arg value="ChangAnFord" index="0"></constructor-arg> <constructor-arg value="250000" type="float"></constructor-arg> </bean> <bean id="car2" class="com.atguigu.spring.helloworld.Car"> <constructor-arg value="ChangAnMazda"></constructor-arg> <!-- 若字面值中包含特殊字符, 則可以使用 CDATA 來進行賦值. (瞭解) --> <constructor-arg> <value><![CDATA[<ATARZA>]]></value> </constructor-arg> <constructor-arg value="180" type="int"></constructor-arg> </bean> <!-- 配置 bean --> <bean id="dao5" class="com.atguigu.spring.ref.Dao"></bean> <bean id="service" class="com.atguigu.spring.ref.Service"> <!-- 引用類型用ref --> <property name="dao" ref="dao5"></property> </bean> <!-- 用bean標籤來配置內部bean --> <bean id="service2" class="com.atguigu.spring.ref.Service"> <property name="dao"> <!-- 內部 bean, 類似於匿名內部類對象. 不能被外部的 bean 來引用, 也沒有必要設置 id 屬性 --> <bean class="com.atguigu.spring.ref.Dao"> <property name="dataSource" value="c3p0"></property> </bean> </property> </bean> <bean id="action" class="com.atguigu.spring.ref.Action"> <property name="service" ref="service2"></property> <!-- 設置級聯屬性(瞭解) --> <property name="service.dao.dataSource" value="DBCP2"></property> </bean> <bean id="dao2" class="com.atguigu.spring.ref.Dao"> <!-- 爲 Dao 的 dataSource 屬性賦值爲 null, 若某一個 bean 的屬性值不是 null, 使用時需要爲其設置爲 null(瞭解) --> <property name="dataSource"><null/></property> </bean> <!-- 裝配集合屬性 --> <bean id="user" class="com.atguigu.spring.helloworld.User"> <property name="userName" value="Jack"></property> <property name="cars"> <!-- 集合屬性就用個list標籤 --> <list> <ref bean="car"/> <ref bean="car2"/> </list> </property> </bean> <!-- 用util命名空間將一個集合作爲一個工具,其他類可以指向它 --> <util:list id="cars"> <ref bean="car"/> <ref bean="car2"/> </util:list> <bean id="user2" class="com.atguigu.spring.helloworld.User"> <property name="userName" value="Rose"></property> <!-- 引用外部聲明的 list --> <property name="cars" ref="cars"></property> </bean> <!--使用p命名空間,能簡化書寫--> <bean id="user3" class="com.atguigu.spring.helloworld.User" p:cars-ref="cars" p:userName="Titannic"></bean> <!-- 用parent可以在配置文件中繼承配置 --> <bean id="user4" parent="user" p:userName="Bob"></bean> <bean id="user6" parent="user" p:userName="維多利亞"></bean> <!--depends-on,那麼創建這個對象之前必須先創建好depengs-on的對象 --> <bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean> </beans> <!-- 自動裝配: 只聲明 bean, 而把 bean 之間的關係交給 IOC 容器來完成 --> <!-- byType: 根據類型進行自動裝配. 但要求 IOC 容器中只有一個類型對應的 bean, 若有多個則無法完成自動裝配. byName: 若屬性名和某一個 bean 的 id 名一致, 即可完成自動裝配. 若沒有 id 一致的, 則無法完成自動裝配 --> <!-- 在使用 XML 配置時, 自動轉配用的不多. 但在基於 註解 的配置時, 自動裝配使用的較多. --> <bean id="dao" class="com.atguigu.spring.ref.Dao"> <property name="dataSource" value="C3P0"></property> </bean> <!-- 默認情況下 bean 是單例的! --> <!-- 但有的時候, bean 就不能使單例的. 例如: Struts2 的 Action 就不是單例的! 可以通過 scope 屬性來指定 bean 的作用域 --> <!-- prototype: 原型的. 每次調用 getBean 方法都會返回一個新的 bean. 且在第一次調用 getBean 方法時才創建實例 singleton: 單例的. 每次調用 getBean 方法都會返回同一個 bean. 且在 IOC 容器初始化時即創建 bean 的實例. 默認值 --> <bean id="dao2" class="com.atguigu.spring.ref.Dao" scope="prototype"></bean> <bean id="service" class="com.atguigu.spring.ref.Service" autowire="byName"></bean> <bean id="action" class="com.atguigu.spring.ref.Action" autowire="byType"></bean> <!-- 因爲有些對象的屬性是需要改變的,爲了維護的方便,將配置信息寫在外部的資源文件當中 導入classpath下名字叫db.properties的資源文件 --> <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> <!--spring表達式語言SpEL:使用 #{…} 作爲定界符,所有在大框號中的字符都將被認爲是 SpEL 可以爲屬性進行動態的賦值, 調用靜態方法或靜態屬性:通過 T() 調用一個類的靜態方法,它將返回一個 Class Object, 然後 再調用相應的方法或屬性 支持運算符 引用bean,和bean的屬性和方法 --> <bean id="girl" class="com.atguigu.spring.helloworld.User"> <property name="userName" value="周迅"></property> </bean> <bean id="boy" class="com.atguigu.spring.helloworld.User" init-method="init" destroy-method="destroy"> <property name="userName" value="#{T(java.lang.MATH).PI*20}"></property> <property name="userName" value="高勝遠"></property> <property name="wifeName" value="#{girl.userName}"></property> </bean> <!-- 配置 bean 後置處理器: 不需要配置 id 屬性, IOC 容器會識別到他是一個 bean 後置處理器, 並調用其方法 --> <bean class="com.atguigu.spring.ref.MyBeanPostProcessor"></bean>
IOC容器管理bean的生命週期
Spring IOC 容器可以管理 Bean 的生命週期, Spring 允許在 Bean 生命週期的特定點執行定製的任務.
在 Bean 的聲明裏設置 init-method 和 destroy-method 屬性, 爲 Bean 指定初始化和銷燬方法.
Spring IOC 容器對 Bean 的生命週期進行管理的過程:
–通過構造器或工廠方法創建 Bean 實例
–爲 Bean 的屬性設置值和對其他 Bean 的引用
–調用 Bean 的初始化方法
–Bean 可以使用了
–當容器關閉時, 調用 Bean 的銷燬方法
<!--init()和destory()方法都是類中聲明的--> <bean id="person" class="com.neusoft.person" p:name="zhangsan" init-method="init" destory-method="destory"> </bean>
Bean 後置處理器允許在調用初始化方法前後對 Bean 進行額外的處理.
Bean 後置處理器對 IOC 容器裏的所有 Bean 實例逐一處理, 而非單一實例. 其典型應用是: 檢查 Bean 屬性的正確性或根據特定的標準更改 Bean 的屬性.
對Bean 後置處理器而言, 需要實現接口BeanPostProcessor. 在初始化方法被調用前後, Spring 將把每個 Bean 實例分別傳遞給上述接口的以下兩個方法:
postProcessBeforeInitialization()方法和 postProcessAfterInitialization()方法
通過調用靜態工廠方法和實例工廠方法創建 Bean
factorybean的方式配置bean
有些對象是通過系統給定的factorybean來配置得到的
繼承factorybean的類通過getobject方法返回一個對象,給放到容器中.
配置文件只需要知道factorybean的類和給類的屬性賦值,然後就會給容器中添加factorybean的getObject()方法返回的對象
通過註解配置bean
組件掃描(component scanning): Spring 能夠從 classpath下自動掃描, 偵測和實例化具有特定註解的組件
特定組件包括:
–@Component: 基本註解, 標識了一個受 Spring 管理的組件
–@Respository: 標識持久層組件
–@Service: 標識服務層(業務層)組件
–@Controller: 標識表現層組件
對於掃描到的組件, Spring 有默認的命名策略: 使用非限定類名, 第一個字母小寫. 也可以在註解中通過 value 屬性值標識組件的名稱
<!-- base-package 屬性 Spring 容器將會掃描這個基類包裏及其子包中的所有類. 當需要掃描多個包時, 可以使用逗號分隔 ,resource-pattern 屬性過濾特定的類--> <context:component-scan base-package="com.test.beans" resourse-pattern="auto/*.class"/> <!-- [!CDATA[<context:include-filter> 子節點表示要包含的目標類 <context:exclude-filter> 子節點表示要排除在外的目標類 <context:component-scan> 下可以擁有若干個 <context:include-filter> 和 <context:exclude-filter> 子節點]]-->
使用 @Autowired給屬性註解
通過給屬性加這個註解,spring就會自動給這個屬性賦值.
–構造器, 普通字段(即使是非 public), 一切具有參數的方法都可以應用@Authwired註解
–默認情況下, 所有使用 @Authwired註解的屬性都需要被設置. 當 Spring 找不到匹配的 Bean 裝配屬性時, 會拋出異常, 若某一屬性允許不被設置, 可以設置 @Authwired註解的 required 屬性爲 false
–默認情況下, 當 IOC 容器裏存在多個類型兼容的 Bean 時, 通過類型的自動裝配將無法工作. 此時可以在 @Qualifier 註解裏提供 Bean 的名稱. Spring 允許對方法的入參標註 @Qualifiter已指定注入 Bean 的名稱
–@Authwired註解也可以應用在數組類型的屬性上, 此時 Spring 將會把所有匹配的 Bean 進行自動裝配.
–@Authwired註解也可以應用在集合屬性上, 此時 Spring 讀取該集合的類型信息, 然後自動裝配所有與之兼容的 Bean.
@Authwired註解用在 java.util.Map上時, 若該 Map 的鍵值爲 String, 那麼 Spring 將自動裝配與之 Map 值類型兼容的 Bean, 此時 Bean 的名稱作爲鍵值