淺談SSH框架中spring的原理
在ssh項(xiàng)目中,是有明確分工的,spring的作用就相當(dāng)于將struts和hibernate連接起來,是將兩個(gè)沒有關(guān)系的框架的特性,方法,action都放在spring的配置文件中使他們建立關(guān)系。取他門各自所長(zhǎng)。而這些做法他們自己不知道,他們是聽命于spring調(diào)度的,他的的任務(wù)只是做好自己的事情。
這樣做的好處就是任務(wù)結(jié)構(gòu)分明,struts只管理顯示與做什么,hibernate只關(guān)心怎么做,而spring就相當(dāng)于領(lǐng)導(dǎo),所以一切的類都要交給spring的工廠創(chuàng)建,這是一種良好的開發(fā)模式,體現(xiàn)了一種編程思想,最大的好處就是結(jié)構(gòu)分明,便于維護(hù),一旦項(xiàng)目出現(xiàn)問題,只修改spring文件,而不在你復(fù)雜的程序中去發(fā)現(xiàn)是誰(shuí)在調(diào)用誰(shuí)。
簡(jiǎn)而言之,ssh框架總體是為了解耦合使用的,struts管理表示層,spring管理業(yè)務(wù)邏輯層,hibernate管理持久化層,3個(gè)框架互相不關(guān)聯(lián),spring調(diào)用hibernate、struts調(diào)用spring來做方法調(diào)用,好處在于spring面向接口的設(shè)計(jì),只要你的接口不變,impl變動(dòng)在配置文件中配置就好了,這樣在工程實(shí)施后,可以實(shí)現(xiàn)軟編碼,在異地調(diào)用用的配置文件直接修改配置文件調(diào)用已經(jīng)寫好的類,來增加功能。
下面結(jié)合實(shí)例理解解容器,DI,IOC,耦合,解耦等Spring所涉及的概念,同時(shí)了解Spring的最基本也是最核心的使用方法。
1.Spring容器
Spring容器負(fù)責(zé)對(duì)象的實(shí)例化,對(duì)象生命周期的管理,被Spring管理的對(duì)象稱之為Bean。
例如有Soldier類需要交由Spring容器管理,我們先編寫類
package com.hb; public class Soldier { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
在Spring配置文件中添加如下配置
<</SPAN>bean id="s1" class="com.hb.Soldier"></</SPAN>bean>
初始化Spring容器
public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
從Spring容器中取得對(duì)象實(shí)例
Soldier s1 = (Soldier) context.getBean("s1");
Spring默認(rèn)使用單例的方式創(chuàng)建對(duì)象??梢酝ㄟ^修改的配置改變成其它創(chuàng)建方式。這個(gè)屬性為Scope,稱之為作用域或生命周期,它的值為singleton(單例,默認(rèn)值),prototype(每次產(chǎn)生一個(gè)新的實(shí)例)等。
<</SPAN>bean id="s1" class="com.hb.Soldier" scope="prototype"></</SPAN>bean>
2. 注入方式有setter注入,構(gòu)造注入方式,接口注入(不需掌握)。建議多使用Setter注入方式。
Setter注入:
Soldier類中有一個(gè)屬性name,如何在創(chuàng)建Soldier的時(shí)候使name的值變?yōu)椤盧ANBO”?
配置如下:
<</SPAN>bean id="s1" class="com.hb.Soldier"> <</SPAN>property name="name" value="RANBO"/> </</SPAN>bean>
這樣創(chuàng)建的Soldier對(duì)象的name屬性就有值了,測(cè)試代碼:
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Soldier s1 = (Soldier) context.getBean("s1"); System.out.println(s1.getName()); }
構(gòu)造注入:
我們先修改下Soldier類,給它添加一個(gè)構(gòu)造方法:
package com.hb; public class Soldier { private String name; public Soldier(String name) { this.name = name; } public String getName() { return name; } }
配置如下:
<</SPAN>bean id="s1" class="com.hb.Soldier"> <</SPAN>constructor-arg value="RANBO"></</SPAN>constructor-arg> </</SPAN>bean>
測(cè)試結(jié)果同上。
3. 依賴
當(dāng)A對(duì)象使用了B對(duì)象的方法,A對(duì)B產(chǎn)生依賴,稱之為A依賴B。下面的例子中Soldier類依賴HandGun類。
package com.hb; public class Soldier { public void fight(){ HandGun handGun = new HandGun(); handGun.killEnemy(); } } package com.hb; public class HandGun { public void killEnemy(){ System.out.println("手槍殺敵"); } }
當(dāng)HandGun發(fā)生變化時(shí),必然導(dǎo)致Soldier必須做相應(yīng)修改,同時(shí),當(dāng)Soldier需要使用OtherGun時(shí)也必須重新編寫代碼,導(dǎo)致代碼重用度不高。
當(dāng)對(duì)象之間的依賴關(guān)系很強(qiáng)時(shí)(耦合),會(huì)使程序代碼死板,不利于后期的維護(hù)和擴(kuò)展。降低對(duì)象之間的依賴關(guān)系稱之為解耦。Spring能夠很好的解決這一問題。
4. 控制反轉(zhuǎn)(Inversion of Control,簡(jiǎn)稱IOC)和依賴注入(Dependence Inject簡(jiǎn)稱DI)
我們運(yùn)用Spring的setter注入方式解決HandGun和Soldier的耦合問題。修改Soldier的代碼,將HandGun定義為Soldier的屬性并提供setter方法:
package com.hb; public class Soldier { private HandGun handGun; public void setHandGun(HandGun handGun) { this.handGun = handGun; } public void fight(){ handGun.killEnemy(); } }
配置如下
<</SPAN>bean id="s1" class="com.hb.Soldier"> <</SPAN>property name="handGun"> <</SPAN>ref bean="handgun"></</SPAN>ref> </</SPAN>property> </</SPAN>bean> <</SPAN>bean id="handgun" class="com.hb.HandGun"></</SPAN>bean>
到這里,我們已經(jīng)降低了HandGun和Soldier的部分依賴關(guān)系,至少在Soldier中不用再自己去實(shí)例化HandGun了。然而并沒有徹底解決問題,Soldier中仍然可以看到HandGun類,因此我們使用接口進(jìn)一步改進(jìn)代碼:
package com.hb; public interface Weapon { void killEnemy(); } package com.hb; public class HandGun implements Weapon{ public void killEnemy(){ System.out.println("手槍殺敵"); } } package com.hb; public class Soldier { private Weapon weapon; public void setWeapon(Weapon weapon) { this.weapon = weapon; } public void fight(){ weapon.killEnemy(); } }
配置如下
<</SPAN>bean id="s1" class="com.hb.Soldier"> <</SPAN>property name="weapon"> <</SPAN>ref bean="handgun"></</SPAN>ref> </</SPAN>property> </</SPAN>bean> <</SPAN>bean id="handgun" class="com.hb.HandGun"></</SPAN>bean>
測(cè)試:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Soldier s1 = (Soldier) context.getBean("s1"); s1.fight();
至此,我們使用Spring很好的解決了HandGun和Soldier的耦合問題。Soldier類中再也看不到HandGun的蹤影了,Soldier只依賴于接口,而最終Soldier還是使用了HandGun,這是為什么呢?Spring在這里管理了單個(gè)的對(duì)象,也管理了對(duì)象之間即Soldier和HandGun的依賴關(guān)系。原本是由Soldier控制HandGun的實(shí)例化的,轉(zhuǎn)變?yōu)橛蒘pring容器來控制,這里發(fā)生了控制權(quán)的轉(zhuǎn)移,這就是控制反轉(zhuǎn)(Inversion of Control,簡(jiǎn)稱IOC)。當(dāng)Soldier需要HandGun時(shí),Spring會(huì)自動(dòng)將HandGun對(duì)象注入給Soldier,這就是依賴注入了。
以上這篇淺談SSH框架中spring的原理就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決SpringBoot連接SqlServer出現(xiàn)的問題
在嘗試通過SSL與SQL?Server建立安全連接時(shí),如果遇到“PKIX?path?building?failed”錯(cuò)誤,可能是因?yàn)槲茨苷_配置或信任服務(wù)器證書,當(dāng)"Encrypt"屬性設(shè)置為"true"且"trustServerCertificate"屬性設(shè)置為"false"時(shí),要求驅(qū)動(dòng)程序使用安全套接字層(SSL)加密與SQL?Server建立連接2024-10-10基于java實(shí)現(xiàn)具有時(shí)效性文件鏈接
這篇文章主要為大家詳細(xì)介紹了如何基于java實(shí)現(xiàn)具有時(shí)效性的文件鏈接,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下2023-12-12mybatis不加@Parm注解報(bào)錯(cuò)的解決方案
這篇文章主要介紹了mybatis不加@Parm注解報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11解決idea中Terminal終端無法執(zhí)行GIT命令+Terminal 中文亂碼問題
這篇文章主要介紹了解決idea中Terminal終端無法執(zhí)行GIT命令+Terminal 中文亂碼問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07解決@Transaction注解導(dǎo)致動(dòng)態(tài)切換更改數(shù)據(jù)庫(kù)失效問題
這篇文章主要介紹了解決@Transaction注解導(dǎo)致動(dòng)態(tài)切換更改數(shù)據(jù)庫(kù)失效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09詳解Java的Spring框架下bean的自動(dòng)裝載方式
這篇文章主要介紹了Java的Spring框架下bean的自動(dòng)裝載方式,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12