spring(一)控制反轉和依賴注入
阿新 • • 發佈:2018-12-19
控制反轉降低了類和類之間的耦合度,利於修改和擴充套件,提供了完整的IOC實現,讓我們專注於業務類和Dao類的設計,體現的是面向介面程式設計的思想,核心是BeanFactory。
需要引入的架包:
commons-logging: spring執行依賴這個元件;
此外還要spring-beans;spring-context;spring-core;spring-expression元件。
本例定個三個介面;Print(印表機),Paper(紙張),Ink(墨盒)
例如:印表機用彩色墨盒在A4紙上列印。
一、初始簡單控制反轉
1. 建立紙張介面和實現類
public interface Paper { public String getSize(); }
public class A4Paper implements Paper{
private String size="A4";
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
2. 建立配置檔案applicationContext.xml
新增resource路徑,用來放配置檔案;
applicationContext.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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1.IoC控制反轉 建立物件,通過bean元素宣告需要Spring例項,即物件,id為例項指定名稱,class指明瞭物件的型別 --> <bean id="A4" class="com.A4Paper"></bean> </beans>
3. 測試
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Paper paper = (Paper)ac.getBean("A4");
System.out.println(paper.getSize());
}
}
輸出: A4。
不用再像以前一樣通過new A4Paper()來建立物件,都交給了容器實現,實現瞭解耦。
二、注入值
以上的A4Paper的值是實現了中設定的,現在通過spring 的DI(依賴注入)來設定值。
1. 增加Ink介面和實現類
public interface Ink {
public String getColor();
}
public class ColorsInk implements Ink{
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
不設定具體的值,再配置檔案中注入。
2.. 增加print類
public class Print {
private Paper paper;
private Ink ink;
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public Ink getInk() {
return ink;
}
public void setInk(Ink ink) {
this.ink = ink;
}
/**
*
*/
public Print() {
super();
}
/**
* @param paper
* @param ink
*/
public Print(Paper paper, Ink ink) {
super();
this.paper = paper;
this.ink = ink;
}
public void print(){
System.out.println("使用"+ink.getColor()+"墨盒,在"+paper.getSize()+"紙上列印");
}
}
兩個介面引數,不關注具體的實現,只關注介面的使用。
3. applicationContext.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 1.IoC控制反轉
建立物件,通過bean元素宣告需要Spring例項,即物件,id為例項指定名稱,class指明瞭物件的型別 -->
<bean id="A4" class="com.A4Paper"></bean>
<bean id="color" class="com.ColorsInk">
<property name="color" value="紅色"></property>
</bean>
<bean id="print" class="com.Print">
<!-- 2.DI依賴注入,面向介面程式設計 setter注入,可以把ref作為標籤寫在外邊,必須有無參構造,在物件建立後賦值
把一個例項注入到另一個例項的屬性,用ref注入,name指定set後的屬性,在本容器中完成的-->
<property name="ink" ref="color"/>
<property name="paper">
<ref bean="A4"></ref>
</property>
</bean>
</beans>
4. 測試
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Print print = (Print)ac.getBean("print");
print.print();
}
}
結果: 使用紅色墨盒,在A4紙上列印。
三、幾種依賴注入方式
<!--1. setter注入,可以把ref作為標籤寫在外邊,必須有無參構造,在物件建立後賦值
把一個例項注入到另一個例項的屬性,用ref注入,name指定set後的屬性,在本容器中完成的-->
<bean id="print" class="cn.bdqn.springIoC.Print">
<property name="ink" ref="gray"/>
<property name="paper">
<ref bean="A4"></ref>
</property>
</bean>
<!-- 構造注入 ,必須有有參的構造方法,-->
<bean id="print1" class="cn.bdqn.springIoC.Print">
<constructor-arg index="0">
<ref bean="A5"></ref>
</constructor-arg>
<constructor-arg index="1">
<!-- 引用的類有id -->
<ref bean="color"></ref>
<!-- 沒有建立id,用bean標籤直接引用類 -->
<!-- <bean class="cn.bdqn.springIoC.ColorsInk"></bean> -->
</constructor-arg>
</bean>
<bean id="greet" class="cn.bdqn.springIoC.Greeting">
<!-- 3.setter注入值,給例項的屬性賦值,必須有set方法,value是具體的值,name指定set後的屬性 -->
<property name="person">
<value>嘎子</value>
</property>
<property name="words">
<value>三天不打小鬼子,手都癢癢。--setter注入值,</value>
</property>
</bean>
<!-- 4.constructor-arg構造注入值,構造器 ,必須有構造方法,可以把value當作屬性寫裡邊,也可以放在外邊當作標籤-->
<bean id="rod" class="cn.bdqn.springIoC.Greeting">
<constructor-arg index="0">
<value>Rod</value>
</constructor-arg>
<constructor-arg index="1">
<value>世界上有兩種人,認識二進位制的和不認識二進位制的。--使用constructor-arg構造注入值</value>
</constructor-arg>
<!-- <property name="person">
<value>Rod</value>
</property>
<property name="words">
<value>世界上有兩種人,認識二進位制的和不認識二進位制的。</value>
</property>
-->
</bean>
<!-- 5.p名稱空間實現屬性注入 ,先加p的宣告,在bean內部設定 p:屬性名=”屬性值“,用到的比較少,解析易出錯-->
<bean id="Tom" class="cn.bdqn.springIoC.Greeting" p:person="Tom" p:words="張嘎是個黑胖子--p名稱空間內部設定">
<!-- <property name="person" value="Tom"/>
<property name="words" value="張嘎是個黑胖子"/> -->
</bean>
<!-- 6.注入不同型別的資料,有特殊字元的 -->
<bean id="朱文俊" class="cn.bdqn.springIoC.Greeting">
<property name="person" value="朱文俊">
</property>
<property name="words">
<!-- <value>a>b</value>-->
<value>a<b 採用預定義實體</value>
</property>
</bean>
<!-- 7.集合注入 -->
<bean id="list" class="cn.bdqn.springIoC.Student1">
<property name="person" value="老師">
</property>
<property name="words" value="這是集合的設定值"></property>
<!-- 集合和陣列,用list -->
<property name="list">
<list>
<value>List1</value>
<value>List2</value>
<value>List3</value>
</list>
</property>
<!-- set集合,用set -->
<property name="set">
<set>
<value>List1:兩個一樣的list2,只會顯示一個</value>
<value>List2</value>
<value>List2</value>
</set>
</property>
<!-- map集合用下邊的標籤 -->
<property name="map">
<map>
<entry>
<!-- key的value必須放在外邊 -->
<key ><value>鍵一</value></key>
<value>第一對</value>
</entry>
<entry>
<key ><value>鍵二</value></key>
<value>第二對</value>
</entry>
</map>
</property>
<!-- Properties類集合,用props標籤 -->
<property name="property">
<!-- 輸出null -->
<!-- <null/> -->
<!-- 空的“”,{} -->
<value></value>
<!-- <props>
<prop key="prop1">鍵所對應的值1</prop>
<prop key="prop2">鍵所對應的值2</prop>
<prop key="prop3">鍵所對應的值3</prop>
</props>
-->
</property>
</bean>
</beans>