Spring這個思想,已經推出不少年了。程序員
剛開始的時候,首先是在Java裏面提出,後來也推出了.net的版本。spring
Spring裏面最主要的就是控制反轉(IOC)和依賴注入(DI)這兩個概念。數據庫
網上不少教程都有詳細的介紹這兩個概念和相關的教程,可是至於何時會用獲得Spring,爲何要使用Spring,提到的教程很少。框架
通過研究以後,決定寫個Demo,供你們瞭解。ui
本人是.net程序員,因此會經過下面這個.net項目進行說明,this
開發軟件:VS2017,Framework版本:4.0spa
首先,介紹一下這個項目的基本信息,這是一個經過用戶的Id查找用戶信息的Demo,默認,咱們是到Sql數據庫中進行查找。.net
解決方案裏,總共有3個項目,分別是Cong.Dao,Cong.Model,ConsoleAppcode
其中,Model是最簡單的,裏面只有一個User類,用於表示一個用戶,有用戶的Id、Name、Age、Phone、Remark,關鍵是Remark屬性,用於區分使用Spring的先後對比。orm
1 namespace Cong.Model 2 { 3 public class User 4 { 5 public string Id { get; set; } 6
7 public string Name { get; set; } 8
9 public int Age { get; set; } 10
11 public string Phone { get; set; } 12
13 public string Remark { get; set; } 14
15 public User(string id, string name, int age, string phone, string remark) 16 { 17 this.Id = id; 18 this.Name = name; 19 this.Age = age; 20 this.Phone = phone; 21 this.Remark = remark; 22 } 23
24 public string Hello() 25 { 26 return string.Format("我是{0},聯繫電話是{1},數據來源於:{2}。", Name, Age, Remark); 27 } 28 } 29 }
Cong.Dao裏有一個接口IUserDao和一個類UserSqlDao,接口是爲了擴展性,類是用於做爲數據訪問層,但這裏並非真的鏈接到數據庫,只是寫固定代碼來模擬,代碼以下:
1 namespace Cong.Dao 2 { 3 public interface IUserDao 4 { 5 User GetUserById(string id); 6 } 7 }
1 namespace Cong.Dao 2 { 3 public class UserSqlDao : IUserDao 4 { 5 public User GetUserById(string id) 6 { 7 User ui; 8 if (id.Equals("1")) 9 { 10 ui = new User(id, "德華", 20, "12345678912", "SQL"); 11 } 12 else
13 { 14 ui = new User(id, "學友", 21, "98765432121", "SQL"); 15 } 16
17 return ui; 18 } 19 } 20 }
ConsoleApp就是一個控制檯,咱們經過輸入用戶的Id,就能到數據庫查出用戶的信息。
1 namespace ConsoleApp 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Console.Write("輸入用戶Id:"); 8 string id = Console.ReadLine(); 9 Console.WriteLine(); 10
11 IUserDao ud; 12 ud = new UserSqlDao(); 13
14 User user = ud.GetUserById(id); 15 Console.WriteLine(user.Hello()); 16
17 Console.ReadKey(); 18 } 19 } 20 }
運行結果以下:
到這裏,所有的代碼結束,能夠正常運行了。
可是,若是從此,因爲其餘緣由,須要把數據庫變動爲Oracle,除了數據須要遷移之外,咱們的程序也要進行修改。
修改的方法比較簡單,就是新建一個UserOracleDao,一樣要繼承IUserDao,
1 namespace Cong.Dao 2 { 3 public class UserOracleDao : IUserDao 4 { 5 public User GetUserById(string id) 6 { 7 User ui; 8 if (id.Equals("1")) 9 { 10 ui = new User(id, "德華", 20, "12345678912", "Oracle"); 11 } 12 else
13 { 14 ui = new User(id, "學友", 21, "98765432121", "Oracle"); 15 } 16
17 return ui; 18 } 19 } 20 }
而在控制檯的代碼中,須要把new UserSqlDao() 修改成new UserOracleDao()。
可是,這裏有些問題:
一、新建一個Dao類,是必需要的;
二、須要修改主程序的代碼,而因爲這只是個Demo項目,實際的開發項目中,代碼比這個Demo的多得多,可能也會有Bll層,咱們就要修改多個類的代碼了,頗有可能會改錯,這不便於維護;
三、若是需求是,Sql和Oracle須要同時存在,使用過程當中,由用戶選擇決定,之後可能還有更多的數據庫追加,那麼咱們須要修改的代碼,就變得更多更復雜了。
因此,這個時候就可使用Spring了。
爲何使用Spring?
Spring能夠下降代碼的耦合度,便於擴展,便於維護。
使用Spring有什麼好處?
可讓咱們在後期維護程序時,大幅度減小修改代碼的量,下降出錯的機率。
直接上代碼吧。
首先,咱們仍是須要建好上面說到的UserOracleDao類。
而後,在ConsoleApp項目中,經過Nuget安裝「Spring.Core」,而且新建一個App.config,
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3
4 <configSections>
5 <sectionGroup name="spring">
6 <!--跟下面Spring.Net節點配置是一一對應關係-->
7 <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
8 <section name="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/>
9 </sectionGroup>
10 </configSections>
11
12 <!--Spring.Net節點配置-->
13 <spring>
14 <!--容器配置-->
15 <context>
16 <resource uri="config://spring/objects"/>
17 </context>
18 <objects>
19 <!--objects裏面放容器的全部節點-->
20 <description>An example that demonstrates simple Ioc features.</description>
21 <!--name 必需要惟一的,type = 類的全名稱,所在的程序集-->
22 <object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object>
23
24 </objects>
25 </spring>
26
27 <startup>
28 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
29 </startup>
30
31 </configuration>
控制檯的代碼修改成:
1 namespace ConsoleApp 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Console.Write("輸入用戶Id:"); 8 string id = Console.ReadLine(); 9 Console.WriteLine(); 10
11 IUserDao ud; 12
13 //IOC
14 IApplicationContext ctx = ContextRegistry.GetContext(); 15 ud = (IUserInfoDao)ctx.GetObject("UserDao"); 16
17 User user = ud.GetUserById(id); 18 Console.WriteLine(user.Hello()); 19
20 Console.ReadKey(); 21 } 22 } 23 }
解釋一下,在配置文件中,加入了<object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object>,定義了一個鍵值對,鍵是用UserDao,對應的是要用的類,就是UserSqlDao,而後在控制檯中,經過IOC容器,加載鍵爲UserDao的值,new一個UserSqlDao的類,這個過程當中,代碼只會以鍵爲主,沒有涉及具體的類。至於實際使用時,new哪個類,全憑配置文件來定義。
例如,若是我想換爲Oracle,就把值修改成「Cong.Dao.UserOraclelDao,Cong.Dao」
這就與傳統的寫法有很大的差異,傳統的寫法是經過代碼來指定用哪一個類,Spring是經過寫接口,固定的代碼,在代碼中調用配置文件中的鍵,而真正決定用哪一個類,是由配置文件來決定的。這就叫作控制反轉。
IOC容器能夠理解爲,我創建一個容器,用於new類,可是我並不關心具體有什麼類。反正當我要使用的時候,我往容器裏傳入鍵,在配置文件裏寫入鍵值對,IOC容器就能返回我要的類。
這種作法,最大的優勢就是,new的動做,都集中在配置文件中,一目瞭然,管理方便。
相似的框架還有Mybatis。
當咱們開發一套程序時,爲了之後的擴展性,能夠加入Spring,咱們能夠爲二次開發人員提供接口,他們就能夠本身寫擴展類,加入配置文件。
也能夠把擴展的類,所有作成選項功能,讓用戶去選擇。這個功能,對於Web項目,十分有用。
想下載Demo源代碼的朋友,能夠到如下地址:
https://download.csdn.net/download/cycong108/10974093
(說明:因爲Spring.net的包有23M,爲了下載方便,我已經刪除了安裝包,須要運行的朋友,請自行下載安裝,版本以下圖)
寫的內容有點亂,若有發現不足的地方,歡迎指出。