前言
Spring
, 是一個輕量級的控制反轉(zhuǎn)(IOC)
和面向切面(AOP)
的容器框架
1.控制反轉(zhuǎn) IOC
(inversion of controller)
IOC 是一種概念, 是吧我們程序中類與類之間的依賴關(guān)系交給容器處理, 一般有兩種方式
-
依賴查找
DL (dependency lookup)
程序提供查找方式, 交給容器去查找(回調(diào)函數(shù))
-
依賴注入
DI (dependency injection)
程序不提供查找方式, 提供合適的構(gòu)造方法或者setter方法,讓容器進行注入來解決依賴關(guān)系
spring 的控制反轉(zhuǎn)就是通過依賴注入來實現(xiàn)的
2.什么叫依賴
簡單的說,一個類實現(xiàn)某個功能需要依賴另一個類的幫助來實現(xiàn)
舉個簡單的例子
將類抽象為某一件事物,不同的類為不同的事物, 比如我們現(xiàn)在有一個 菜刀類
和一個 肉類
, 如果我們現(xiàn)在想要菜能夠?qū)⑷馇谐善? 而后才能進行后臺的烹飪. 但是我們發(fā)現(xiàn)光憑 菜刀
和 肉
根本無法達到我們想要的效果, 我們想要叫肉變成肉片, 還必須借助一個菜板類
,也只有借助菜板
, 我們才能達到我們想要的想過, 而現(xiàn)在 菜刀
和 菜板
也就存在依賴的關(guān)系
用程序舉一個例子
目標(biāo): 我們將模擬一個web登錄驗證功能
創(chuàng)建兩個文件 UserDao.java
UserService.java
UserDao.java
作為數(shù)據(jù)持久層,連接數(shù)據(jù)庫, 提供鏈接數(shù)據(jù)庫, 判斷數(shù)據(jù)庫中用戶名和密碼是否正確
UserDao
public class UserDao{
public boolean loginUser(String userName, String password) {
System.out.println("這是通過jdbc進行登陸驗證的dao方法");
return true;
}
}
UserService.java
作為業(yè)務(wù)邏輯層, 調(diào)用數(shù)據(jù)持久層進行具體業(yè)務(wù)編寫
UserService
/**
* 類描述:用于對關(guān)于用戶登陸,用戶增刪改查的服務(wù)類(service)
* @author atom.hu
*
*/
public class UserService {
/**
* 通過調(diào)用與數(shù)據(jù)庫交互的UserDao里面的loginUser方法,判斷是否驗證成功
* @param userName
* @param password
* @return
*/
public boolean loginUser(String userName,String password){
boolean flag = false;
//在userService中,,為了實現(xiàn)登陸的驗證,需要調(diào)用Dao的方法
UserDao userDao = new UserDao();
//IUserDao userDao = new UserDaoOther();
flag = userDao.loginUser(userName, password);
return flag;
}
}
這里我們在UserService
中創(chuàng)建main
方法, 模擬進行調(diào)用
public static void main(String[] args) {
UserService userService = new UserService();
userService.loginUser("aaa", "bbb");
}
至此, 我們就模擬了一個簡單的登錄功能, 不難發(fā)現(xiàn)按照傳統(tǒng)的mvc 模式, 我們需要使用 dao , service, controller 三層結(jié)合起來使用, 每層負責(zé)自己的事,
在上的代碼中 UserService 中調(diào)用UserDao中的代碼, 它們便就存在依賴關(guān)系(圖中紅線框類)
3.面向接口編程
上面介紹了依賴的情況, 然后在實際開發(fā)中,都需要使用接口定義公共方法, 實現(xiàn)(implement)
接口, 針對具體方法進行實現(xiàn)
在實際開發(fā)中,隨著項目的開展, 需求不時也會發(fā)生變化, 詳細到每一個功能點, 今天這個功能點需要實現(xiàn)A功能, 明天業(yè)務(wù)可能就會變成B功能, 再往后也有可能在回到A功能, 在針對著這樣多變的開發(fā)環(huán)境下, 針對接口編程就變得尤為重要
星期一
星期二, 老板心情不太好, 想要換個樣子
星期三
老板看了看覺得這個顏色好像有點不妥, 于是便又換了個樣子
此時的你
星期四
星期五 老板覺得, 看來看去, 還是覺得星期一的比較好
盡管你再不想改, 但是為了生存你還是要去做, 然后這樣的工作, 其實更多的是體力活, 對于技術(shù)而言增長不大
然后其實我們可以很好的避免這一點
我們需要定義一個公共的接口 IService
, 接口中定義需要實現(xiàn)的功能列表, 然后我們只需要創(chuàng)建多個不同的實現(xiàn)類即可
如上圖所示, 再實現(xiàn)具體的功能時只需要通過接口new
對應(yīng)的對象即可
今天要實現(xiàn)A功能
IService ServiceA = new ServiceAImpl();
今天要實現(xiàn)B功能
IService ServiceB = new ServiceBImpl();
今天要實現(xiàn)C功能
IService ServiceB = new ServiceBImpl();
這樣而言, 無論需求如果改變都不再害怕