Spring通俗理解與實踐
接觸Java EE方面的朋友,尤其是對於入門級別的同學,對於Java EE框架spring+spring mvc+mybatis(SSM)或者spring+struts2+hibernate(SSH)三大框架中,對於Spring是最難以理解的。為何這麼說?因為博主在學習這個方面的時候,和許多同學都產生過這個困惑,所以百度上都會有類似"Spring是做什麼的?誰能講講Spring到底是什麼?"這些問題,相信也會有很多入門的同學會有相同的疑惑。
對於上面在百度上問到的問題,一些回答就是copy百度百科的東西貼上去,或者是用著例如IOC,AOP等術語解釋給提問者,並且也不解釋IOC,AOP等名詞的意思。的確可能有些人是大牛,不願在這個問題上去花費他的時間,這也無可厚非,但是有些就是故意使用一些入門者不懂的名詞,來顯擺一下自己是有多厲害,多麼的高深。下面這篇文章就講講Spring的那些事。
其實Spring主要處理的兩大方面在於IOC(控制反轉/依賴注入),AOP(面向切面)。什麼是IOC(Inversion of Control)呢?解決的是解耦的問題,高質量的程式碼一般都要求低耦合,高內聚的特點,這樣會利於維護和測試。著重談一談耦合度,耦合: 舉個簡單得例子,例如指的是兩個子系統或者類彼此之間相互依賴(關聯)的程度,這個程度越低,就說耦合度越低,關聯越密切,則是耦合度越高。兩個類之間,耦合度在不影響整個工程的情況下,儘量要降到最低,注意一個詞"儘量",而不是說全部解耦到一點關聯都沒有,那就是相互都獨立的東西,怎麼還可能去構成一個工程呢?
關於耦合度的概念大家瞭解那麼一點了,下面開始說Spring要做的事IOC。
現在有2個類Student和Teacher類,並且一個學生只能有一個老師,這樣的邏輯。普通處理的程式碼如下:
package xyz.dream.demo //面向介面程式設計 interface Person{ public void eat(); } //教師類 class Teacher implements Person { private String name; private String number; public eat(){ System.out.println("吃飯"); } public String getName(){ return name; } public void setName(String name){ this.name=name; } public String getNumber(){ return number; } public void setNumber(String name){ this.number=number; } } //學生類 class Student{ private Person teacher=new Teacher();//普通的硬程式碼產生teacher物件,使用spring後,不需要寫new Teacher();這段程式碼了,在spring配置檔案配置就行 public void setTeacher(Teacher teacher){ this.teacher=teacher; } public Teacher getTeacher(){ return teacher; }}
此時,從程式碼中可以看出,Student類依賴於Teacher,就是說先是產生過屬性teacher這個物件之後,Student物件才會完整和使用。但是現在有一個問題來了。假如我的
Teacher類的類名改了,我們還得去修改有產生Teacher類物件的地方。有人說改了就是了,沒多大的點事。在程式碼量小的時候的確也不是什麼難事,但是你得考慮一個大型項
目一改一個地方,就會牽一髮而動全身,各式各樣的錯誤就會出現,不利於除錯和維護。
假如我們使用spring的話,硬編碼的那段程式碼就可以省略了,在配置檔案中配置把Teacher物件注入進來就行了。來看看配置的spring.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
"
>
<!--在spring容器中,產生一個名叫teacher的Teacher物件,啟動tomcat後配置啟動引入spring配置檔案後,spring容器會建立,之後會執行下面的配置-->
<bean id="teacher" class="xyz.dream.demo.Teacher"></bean>
<!--在spring容器中,建立名叫student的Student類的物件,並且給一個屬性叫teacher注入名為teacher的物件,就是上面那個JAVA Bean物件-->
<bean id="student" class="xyz.dream.demo.Student">
<property name="teacher" ref="teacher">
</bean>
</bean>
new Teacher();這段程式碼就可以省略了,如果以後你想修改Teacher類名,通過配置檔案修改class的值就行了,是不是方便多了?
通過下面的程式碼測試一下,studentd的一個物件是否會存在於記憶體之中,我們把它取出來看看student這個會正常地執行嗎?
public class Test {
public static void main(String[] args){
//載入spring配置檔案,獲取到容器物件
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
//從容器中取出名為studnet的物件
/* <bean id="student" class="xyz.dream.demo.Student">
<property name="teacher" ref="teacher">
</bean>
*/
Student student=(Student) applicationContext.getBean("student");
student.getTeacher().eat();
}
}
控制檯會輸出"吃飯"這個詞,表明了我們的teacher這個物件注入到studnet物件的teacher的那個屬性當中去了,載入配置檔案後,spring建立的兩個物件都在記憶體中,我們
通過容器物件取出studnet這個物件無誤,表明了spring這個容器是可以做到這一點的,減少了硬編碼通過new 的形式來獲取物件。
spring功能很強大,我這個只是其中一個小例子,是對入門的同學起到一點點對spring理解的作用,希望能幫助到你們。IOC(依賴注入/控制反轉)這個小案例,大家看後能多
多少少有那麼點理解。筆者水平有限,若出現某些知識點理解錯誤的地方希望海涵,謝謝!