?IoC ( Inver sion of Control )稱之為控制反轉,指的是在 Spring 框架的配置文件中聲明對象,由框架負責創建對象,這叫做控制反轉。實現方式有兩種: DI(Dependency Injection) 依賴注入,這也是 Spring 框架的實現方式,主要學習的也是這個; SL ( Service Locator )服務器定位器實現方式。
? ? ? ? ? ? ? DI 依賴注入,就是框架不僅創建了對象,而其還負責初始化相關聯的對象的過程。從實現方式上也分為 3 種方式:
????????????????????? a ,Interface Injection( 接口注入 ) :容器運行時,目標對象實現特定的接口,然后容器通過接口將關聯對象注入到目標對象中。這種方式 Spring 框架不支持,所以了解。
???????????????????? b ,Setter Injection(set 方法注入 ) :容器運行時,通過類屬性的 set 方法將關聯對象注入到目標對象中。 Spring 框架支持,而且是我們開發經常使用的,非常重要。
???????????????????? c ,Constructor Injection( 構造方法注入):容器運行時,通過類的構造方法將關聯對象注入到對象中。 Spring 框架也支持,沒有 set 用的普遍。
?
? ? 好,下邊主要總結一下 set 方法注入和構造方法注入。
?
一, Setter Injection:
? ? 1, 當屬性為簡單字符串時,可以直接增加 property 標簽:例如:
privateString usercode ;
privateString userpswd ;
?
setter方法: 是配置文件中property標簽的name屬性值的set方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????????? < bean ? id = "loginAction" ? class = "com.bjpowernode.struts2.action.LoginAction" ? > ?? ????????????????< property ? name = "usercode" ? value = "admin" > </ property > ?? ????????????????< property ? name = "userpswd" ? value = "admin" > </ property > ?? ????????????</ bean > ?? </ span > ??
?
? ? ? ? ? 2 ,屬性值為引用類型時,通過 property 中的 ref 屬性來關聯對象:
? ?privateUserService userService;
?
? ?setter方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?? < bean ? id = "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ? > ?? ????????< property ? name = "userService" ? ref = "userService" > </ property > ?? ????</ bean > ?? ?? < bean ? id = "userService" ? class = "com.ljh.struts2.service.UserService" > </ bean > ?? </ span > ??
? ? ? ? ?3, 屬性為數組類型時,需要在設置屬性值時,將多個元素通過逗號隔開,或者利用 list 標簽:
privateString[] names ;
?
setter方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????? < bean ? id = "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ? > ?? ????????????< property ? name = "names" ? value = "zhang,san,lisi,wangwu" > </ property > ?? ????????</ bean > ?? </ span > ??
如果賦值操作中,需要將逗號作為一個整體,那么需要通過特殊的標簽進行賦值
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????? < bean ? id = "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ? > ?? ????????????< property ? name = "userService" ? ref = "userService" > </ property > ?? ????????????< property ? name = "names" > ?? ????????????????< list > ?? ????????????????????< value > zhang,san </ value > ?? ????????????????????< value > lisi </ value > ?? ????????????????????< value > wangwu </ value > ????????????????? ????????????????</ list > ?? ????????????</ property > ?? ?? </ bean > </ span > ??
? ? ? ? ? ? ?4 ,屬性為 list 集合時,也是使用 list 標簽:
集合如果使用泛型,只能存儲相同類型的元素,不使用泛型,可以存儲不同類型的元素:
privateList<String> nameList ;
?
setter方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????????????? < bean ? id = "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ? > ?? ????????????????????< property ? name = "nameList" > ?? ????????????????????????< list > ?? ????????????????????????????< value > zhang,san </ value > ?? ????????????????????????????< value > lisi </ value > ?? ????????????????????????????< value > wangwu </ value > ????????????????? ????????????????????????</ list > ?? ????????????????????</ property > ?? ?? </ bean > ??? </ span > ??
? ? ? ? ? ? ?5 ,當屬性為 map 集合時,需要使用 map 標簽:
P rivate Map map ;
?
setter方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????? < bean ? id = "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ? > ?? ????????????< property ? name = "map" > ?? ????????????????< map > ?? ????????????????????< entry ? key = "hello" ? value = "world" > </ entry > ?? ????????????????????< entry ? key-ref = "userService" ? value-ref = "userService" > </ entry > ?? ????????????????</ map > ?? ????????????</ property > ?? ????????</ bean > ????????????? ?? < bean ? id = "userService" ? class = "com.ljh.struts2.service.UserService" > </ bean > </ span > ??
? ? ? ? ? ? ? 6, 屬性為Properties集合類型時,需要在設置屬性值時,增加props標簽
?
privateProperties props ; //繼承了Hashtable,是線程安全的
?
setter方法
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????????? < bean ? id = "loginAction" ? class = "com.bjpowernode.struts2.action.LoginAction" ? > ?? ????????????????< property ? name = "props" > ?? ????????????????????< props > ?? ????????????????????????< prop ? key = "url" > jdbc:oracle:thin:@192.168.1.27:1521:ljh </ prop > ?? ????????????????????????< prop ? key = "driverName" > oracle.jdbc.driver.OracleDriver </ prop > ?? ????????????????????????< prop ? key = "username" > scott </ prop > ?? ????????????????????????< prop ? key = "password" > tiger </ prop > ?? ????????????????????</ props > ?? ????????????????</ property > ?? ?? </ bean > </ span > ??
? ? ?總結 : 以上為幾種常用屬性類型的 set 注入的寫法, set 方法注入,框架是先通過默認的無參構造方法進行創建對象,然后進行 set 注入的。當然如果我們重寫了構造方法,沒有了無參構造呢?這就需要下邊的構造方法注入了。
?
?
??????? 二, Constructor Injection
?????????????? 1 ,例如我們聲明了有參構造方法,就需要通過次構造方法進行創建對象和關聯對象了,利用 constructor-arg 標簽:
[java] ?view plaincopy print?
<span?style= "font-size:18px;" > ?? ????????????super ();?? ????????????this .usercode?=?usercode;?? ?? }</span>??
[java] ?view plaincopy print?
<span?style= "font-size:18px;" >??????<!--??通過value屬性指定其值-->?? ????????<bean?id="loginAction" ? class = "com.ljh.struts2.action.LoginAction" ?>?? ????????????<constructor-arg?value="admin" ></constructor-arg>????????????????? ????????</bean>?? </span>??
? ? ? ? ? 2 ,如果我們有多個無參構造方法,里邊參數可能不同,順序可能不同等!怎么辦呢?其中框架會根據制定的參數個數, type 制定的類型, inde x 制定的先后順序來查找我們想要的構造方法,來進行初始化和對象關聯。
[java] ?view plaincopy print?
<span?style= "font-size:18px;" >??????<bean?id= "loginAction" ? class = "com.ljh.struts2.action.LoginAction" ?>?? ????????????<constructor-arg?value="admin" ?index= "0" ></constructor-arg>?? ????????????<constructor-arg?value="22" ?type= "int" ?index= "1" ></constructor-arg>??? ?? </bean></span>??
? ? ? ? ? 3 ,構造方法和 set 方法同時使用也是可以的,它們兩者的標簽沒有先后順序問題,框架會先調用帶參數的構造方法創建對象,然后構造注入數據,再調用 set 方法進行屬性注入。但是自我感覺這種方法盡量少用。
[html] ?view plaincopy print?
< span ? style = "font-size:18px;" > ?????? < bean ? id = "loginAction" ? class = "com.bjpowernode.struts2.action.LoginAction" ? > ????????????? ????????????< constructor-arg ? value = "admin" ? index = "0" > </ constructor-arg > ??????? ????????????< constructor-arg ? value = "23" ? type = "int" ? index = "1" > </ constructor-arg > ?? ????????????< property ? name = "userpswd" ? value = "admin" > </ property > ??? ?? </ bean > ??? </ span > ??
? ? ? ? ?? 三,自動裝配功能,就是框架會自動為我們匹配,利用autowire標簽來實現,注意這種自動裝配功能不支持簡單類型( String ,int , date 等)他有 6 個值 by Name,byType ,constructor,autodetect,no,default。從字面類型大概看個差不多吧。簡單說一下。
??????????? 1 , byName ( 根據名稱 ), 從Spring環境中獲取目標對象時,目標對象中的屬性會 根據名稱 在整個Spring環境中查找<bean>標簽的id屬性值 :
<bean id="loginAction"class="com. ljh .struts2.action.LoginAction"autowire="byName" ></bean>
?
?????????? 2.byType( 根據類型 ) ,從Spring環境中獲取目標對象時,目標對象中的屬性會 根據類型 在整個spring環境中查找<bean>標簽的class屬性值 :
<bean id="userService"class="com. ljh .struts2.service.UserService"autowire="byType" ></bean>
?
?????????? 3, ?constructor : 使用構造方法完成對象注入,其實也是根據構造方法的參數類型進行對象查找,相當于采用byType的方式。
?
?????????? 4, autodetect ( 自動選擇 ): 如果對象沒有無參數的構造方法,那么自動選擇constructor的自動裝配方式進行構造注入。 ?????? 如果對象含有無參數的構造方法,那么自動選擇byType的自動裝配方式進行setter注入。
?
????????? 5 ,no:表示不支持自動裝配功能;
?
????????? 6 , default :表示默認采用上一級標簽的自動裝配的取值。<beans>標簽中的default-autowire屬性。如果存在多個配置文件的話,那么每一個配置文件的自動裝配方式都是獨立的。
?????
? ? ? ? ?? 分析總結,自動裝配就是為了彌補手動裝配,如果兩者都使用,優先選擇手動的。由于自動裝配需要在 Spring 全局環境中搜索,所以性能上會低一些,而且可閱讀性較差,所以還是推薦大家使用手動裝配功能。
?
?
????????? 綜上為 Spring 框架 IOC 的基礎功能,這樣 Spring 對對象的管理,對彼此之間的解耦起到了非常大的作用,使其優秀的重要條件之一。
from:?http://blog.csdn.net/liujiahan629629/article/details/20736011
總結
以上是生活随笔 為你收集整理的Spring(二)——IoC 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。