spring學習(4)
在spring容器內拼湊bean叫做裝配。裝配bean的時候,需要告訴容器哪些bean以及容器如何使用依賴注入將它們配合在一起。
上下文定義檔案的根元素是<beans>,<beans>中有很多<bean>
id不能重複,class要寫全。
scope
prototype,singleton,request,session,global-session,
預設為singleton
使用原型bean會對效能產生影響。
特別強調一點,儘量使用scope=singleton,不要使用原型prototype,因為這樣對我們的效能影響比較大。
例項化和銷燬init-method destroy-method
有時候沒有用init-method destroy-method,卻使用了註解。如:
@PostConstruct public void init(){ System.out.println("我自己的init方法"); }
可以注入任何東西,從基本型別到集合類,甚至可以是應用系統的bean。
②如何給集合型別注入值
java主要有幾種集合:map set list / 陣列
Collection col = new ArrayList()
col只能使用Collection本身有的方法,但是卻可以呼叫被ArrayList實現了的方法。
set使用方法和list一樣。
注入list和set。
list中可以注入許多相同的bean
set也可以,但是後面的會把前面的覆蓋。
Department類
Employee類
陣列的使用:
Depart類
package com.hsp.collection; import java.util.List; import java.util.Map; import java.util.Set; public class Department { private String name; private String[] empName;private List<Employee> empList; private Set<Employee> empsets; private Map<String,Employee> empMaps; public Map<String, Employee> getEmpMaps() { return empMaps; } public void setEmpMaps(Map<String, Employee> empMaps) { this.empMaps = empMaps; } public Set<Employee> getEmpsets() { return empsets; } public void setEmpsets(Set<Employee> empsets) { this.empsets = empsets; } public List<Employee> getEmpList() { return empList; } public void setEmpList(List<Employee> empList) { this.empList = empList; } public String[] getEmpName() { return empName; } public void setEmpName(String[] empName) { this.empName = empName; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
//Employee類
package com.hsp.collection; public class Employee { private String name; private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
beans.xml配置檔案
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd "> <bean id="department" class="com.hsp.collection.Department"> <property name="name" value="財務部"> </property> <property name="empName"><!-- 陣列 --> <list> <value>小明</value> <value>大明</value> <value>大大明</value> </list> </property> <!-- 給list注入值 --> <property name="empList"> <list> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> </list> </property> <!-- 給set注入值 --> <property name="empsets"> <set> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> </set> </property> <!-- 給map注入值 --> <property name="empMaps"> <map> <entry key="1" value-ref="emp1" /> <entry key="2" value-ref="emp2" /> </map> </property>
<!-- 給屬性集合配置 --> <property name="pp"> <props> <prop key="pp1">abcd</prop> <prop key="pp2">1234</prop> </props> </property>
</bean> <bean id="emp1" class="com.hsp.collection.Employee"> <property name="name" value="北京"/> <property name="id" value="1"/> </bean> <bean id="emp2" class="com.hsp.collection.Employee"> <property name="name" value="天津"/> <property name="id" value="2"/> </bean> </beans>
③內部bean
<bean id="foo" class="...Foo">
<property name="emp">
<!-- 第一方法引用 -->
<ref bean='neibu'/> <bean id="neibu"><!-- 該bean只能在emp裡面使用 --> </bean> </property>
</bean>
④繼承配置
<property name="name" value="順平"/>
name的值是類的屬性名
public class Student
public class Graduate extends Student
在beans.xml檔案中體現配置
<!-- 配置一個學生物件 --> <bean id="student" class="com.hsp.inherit.Student"> <property name="name" value="順平"/> <property name="age" value="30"/> </bean> <!-- 配置graduate物件 --> <bean id="graduate" parent="student" class="com.hsp.inherit.Graduate"> <!-- 如果自己配置屬性name,age,則會替換從父物件繼承的資料 --> <property name="name" value="小明"/> <property name="degree" value="學士"/> </bean>
就如同java裡的子類繼承父類一樣,子類新增的東西會把父類的同名物件覆蓋。
若bean的屬性是集合型別,按如下處理
設定為null
<property name="name">
<null/>
</property>
⑤
思考:目前我們都是通過set方式給bean注入值,spring還提供了其他的方式注入值,比如通過建構函式注入值!
通過建構函式注入值
beans.xml關鍵程式碼
<bean id="employee" class="com.hsp.constructor.Employee"> <!-- 通過建構函式來注入值 --> <constructor-arg index="0" type="java.lang.String" value="大明"/> <!-- <constructor-arg index="1" type="int" value="123"/> --> </bean>
set注入的確定是無法清晰表達哪些屬性是必須的,哪些是可選的,構造注入的優勢是通過構造強制依賴關係,不可能例項化不完全的或無法使用bean。
Spring IoC容器可以自動裝配相互協作bean之間的關聯關係。
自動裝配有5種方式
自動裝配bean的屬性值
自動裝配的原理:
autowire=byName:根據屬性名自動裝配。
比如正好發現有一個bean的id名叫做dog,
原理圖:
(1)byName的用法,去匹配bean的id值與類屬性名相同的bean
<!-- 配置一個master物件 --> <bean id="master" class="com.hsp.autowire.Master" autowire="byName"> <property name="name"> <value>順平</value> </property> </bean> <!-- 配置dog物件 --> <bean id="dog" class="com.hsp.autowire.Dog"> <property name="name" value="小黃"/> <property name="age" value="3"/> </bean>
(2)byType
在沒有匹配到的情況下才會去使用byType。尋找和屬性型別相同的bean。
<!-- 配置一個master物件 --> <bean id="master" class="com.hsp.autowire.Master" autowire="byType"> <property name="name"> <value>順平</value> </property> </bean> <!-- 配置dog物件 --> <bean id="dog11" class="com.hsp.autowire.Dog"> <property name="name" value="小黃"/> <property name="age" value="3"/> </bean>
(3)constructor:查詢和bean的構造引數一致的或多個bean
使用了constructor,就去尋找是否有一個建構函式把dog接收到了,如果找到了就好。
<bean id="master" class="com.hsp.autowire.Master" autowire="constructor"> <property name="name"> <value>順平</value> </property> </bean> <!-- 配置dog物件 --> <bean id="dog11" class="com.hsp.autowire.Dog"> <property name="name" value="小黃"/> <property name="age" value="3"/> </bean>
但是隻能有一個建構函式。
建議:能不用自動裝配就不要用自動裝配,set注入就可以了。
(4)autodotect:(3)和(2)之間選一個方式。不確定性的處理與(3)和(2)一致。
(5)default-autowire="byName" 是寫在 xsi:schemaLocation="">中的
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
" default-autowire="no" >
當你在<beans>指定了default-autowire後,所有的bean的預設的autowire就是指定的裝配方式。
default-autowire預設是no.
(6)no:這是預設值。