Spring初識及其IOC入門
一.框架
框架是一些類和介面的集合,它一個半成品,已經對基礎的程式碼進行了封裝並提供相應的API,開發者在使用框架時直接調用封裝好的api可以省去很多程式碼編寫,從而提高工作效率和開發速度。
二.Spring
2.1.架構的演進:
單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的數據訪問框架(ORM)是關鍵。
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,提升效率的方法之一是將應用拆成互不相干的幾個應用,以提升效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。
分散式服務架構
當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用於提高業務復用及整合的分散式服 務框架(RPC)是關鍵。
流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)是 關鍵。
2.2.spring
2.2.1.核心解釋
spring是一個輕量級開源框架。
spring是為了簡化企業開發而生的,使得開發變得更加優雅和簡潔。
spring是一個IOC和AOP的容器框架。
IOC:控制反轉
AOP:面向切面編程
容器:包含並管理應用對象的生命周期,就好比用桶裝水一樣,spring就是桶,而對象就是水
2.2.2.使用spring的優點
- Spring通過DI、AOP和消除樣板式程式碼來簡化企業級Java開發
- Spring框架之外還存在一個構建在核心框架之上的龐大生態圈,它將Spring擴展到不同的領域,如Web服務、REST、移動開發以及NoSQL
- 低侵入式設計,程式碼的污染極低
- 獨立於各種應用伺服器,基於Spring框架的應用,可以真正實現Write Once,Run Anywhere的承諾
- Spring的IoC容器降低了業務對象替換的複雜性,提高了組件之間的解耦
- Spring的AOP支援允許將一些通用任務如安全、事務、日誌等進行集中式處理,從而提供了更好的復用
- Spring的ORM和DAO提供了與第三方持久層框架的的良好整合,並簡化了底層的資料庫訪問
- Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可自由選用Spring框架的部分或全部
2.3.IOC(inversion of controller) 控制反轉
2.3.1.為什麼要學習IOC
創建一個普通的java項目,實現service層調dao層,dao層是可擴展的。
1.UserDao.java
1 package com.zyj.dao; 2 3 /** 4 * @author zyj 5 * @Package com.zyj.dao 6 */ 7 public interface UserDao { 8 public void getUser(); 9 }
2.UserDaoImpl.java
1 package com.zyj.dao.impl; 2 3 import com.zyj.dao.UserDao; 4 5 /** 6 * @author zyj 7 * @Package com.zyj.dao.impl 8 */ 9 public class UserDaoImpl implements UserDao { 10 @Override 11 public void getUser() { 12 System.out.println("查詢數據....."); 13 } 14 }
3.UserService.java
package com.zyj.service; /** * @author zyj * @Package com.zyj.service */ public interface UserService { public void getUser(); }
4.UserServiceImpl.java
package com.zyj.service.impl; import com.zyj.dao.UserDao; import com.zyj.dao.impl.UserDaoImpl; import com.zyj.dao.impl.UserDaoMysqlImpl; import com.zyj.service.UserService; /** * @author zyj * @Package com.zyj.service.impl */ public class UserServiceImpl implements UserService { private UserDao ud = new UserDaoImpl(); @Override public void getUser() { ud.getUser(); } }
5.測試類
1 package com.zyj.test; 2 3 import com.zyj.service.UserService; 4 import com.zyj.service.impl.UserServiceImpl; 5 6 /** 7 * @author zyj 8 * @Package com.zyj.test 9 */ 10 public class MyTest { 11 public static void main(String[] args) { 12 UserService us = new UserServiceImpl(); 13 us.getUser(); 14 } 15 }
6.運行
7.如果此時要新增dao,例如新增UserDaoMysqlImpl.java,則對應的UserServiceImpl勢必要改動
1 package com.zyj.service.impl; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoImpl; 5 import com.zyj.dao.impl.UserDaoMysqlImpl; 6 import com.zyj.service.UserService; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.service.impl 11 */ 12 public class UserServiceImpl implements UserService { 13 // private UserDao ud = new UserDaoImpl(); 14 private UserDao ud = new UserDaoMysqlImpl(); 15 @Override 16 public void getUser() { 17 ud.getUser(); 18 } 19 }
8.如果項目需要,還要新增dao,例如新增UserDaoOracleImpl.java,則UserServiceDao勢必還要修改,如果項目大的話會造成很大的工作量。很顯然這種方式已經不適用。可以採用如下的方式。
修改UserServiceImpl.java
1 package com.zyj.service.impl; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoImpl; 5 import com.zyj.dao.impl.UserDaoMysqlImpl; 6 import com.zyj.service.UserService; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.service.impl 11 */ 12 public class UserServiceImpl implements UserService { 13 // private UserDao ud = new UserDaoImpl(); 14 // private UserDao ud = new UserDaoMysqlImpl(); 15 private UserDao ud; 16 public void setUserDao(UserDao userDao){ 17 this.ud = userDao; 18 } 19 @Override 20 public void getUser() { 21 ud.getUser(); 22 } 23 }
9.在測試類中,new出來UserDaoOracleImpl類對象,然後調UserServiceImpl類的setUerDao方法的方式來創建對象,MyTest.java修改如下:
1 package com.zyj.test; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoOracleImpl; 5 import com.zyj.service.UserService; 6 import com.zyj.service.impl.UserServiceImpl; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.test 11 */ 12 public class MyTest { 13 public static void main(String[] args) { 14 UserServiceImpl us = new UserServiceImpl(); 15 UserDao ud = new UserDaoOracleImpl(); 16 us.setUserDao(ud); 17 us.getUser(); 18 } 19 }
10.運行
總結:一言以蔽之。從上面的程式碼中我們可以看到解耦(降低程式之間額依賴)的重要性,而使用Spring的IOC可以降低程式之間的耦合性,並提升開發效率,降低成本。
2.3.2.IOC的概念
IOC與大家熟知的依賴注入(DI)同理,這是一個通過依賴注入對象的過程,也就是說,他們所使用的對象,是通過構造函數參數,工廠方法的參數或者是從工廠方法的構造函數或返回值的對象實例設置的屬性,然後容器在創建bean時注入這些需要的依賴,這個過程相對於普通創建對象的過程時反向的,bean本身通過直接構造類來控制依賴關係的實例化或位置,或提供諸如服務定位器模式之類的機制。通俗說法:就是我們開發程式時將通過new關鍵字創建對象的方式交由spring去管理,即spring的IOC(控制反轉)。
2.3.3.DI和IOC
很多人把IOC和DI說成一個東西,籠統來說的話是沒有問題的,但是本質上還是有所區別的,IOC和DI是從不同的角度描述的同一件事,IOC是從容器的角度描述,而DI是從應用程式的角度來描述,也可以這樣說,IOC是設計思想,而DI是具體的實現方式。
2.3.4.IOC基本案例
要求:通過springIOC實現對象的創建,及其屬性的賦值
程式碼實例:
1.Persion.java實體類
1 package com.zyj.entity; 2 3 import org.springframework.core.env.SystemEnvironmentPropertySource; 4 5 /** 6 * @author zyj 7 * @Package com.zyj.entity 8 */ 9 public class Persion { 10 private int id; 11 private String username; 12 private int age; 13 private String address; 14 15 public int getId() { 16 return id; 17 } 18 19 public String getUsername() { 20 return username; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public String getAddress() { 28 return address; 29 } 30 31 public void setId(int id) { 32 this.id = id; 33 } 34 35 public void setUsername(String username) { 36 this.username = username; 37 } 38 39 public void setAge(int age) { 40 this.age = age; 41 } 42 43 public void setAddress(String address) { 44 this.address = address; 45 } 46 47 @Override 48 public String toString() { 49 return "persion{" + 50 "id=" + id + 51 ", username='" + username + '\'' + 52 ", age=" + age + 53 ", address='" + address + '\'' + 54 '}'; 55 } 56 public Persion(){ 57 System.out.println("我被創建了......"); 58 } 59 }
2.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springIOC_01</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> </dependencies> </project>
3.編寫的配置文件ioc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="//www.springframework.org/schema/beans" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//www.springframework.org/schema/beans
//www.springframework.org/schema/beans/spring-beans.xsd"> <!--bean標籤用於創建bean對象,其id屬性表示唯一值,class屬性表示要實例化對象的絕對地址--> <bean id="persion" class="com.zyj.entity.Persion"> <!--perperty標籤用於給屬性值賦值,name代表實體的屬性名稱,value表示實體屬性的賦值--> <property name="id" value="1"></property> <property name="username" value="趙亞軍"></property> <property name="age" value="18"></property> <property name="address" value="北京北京"></property> </bean> </beans>
4.測試啟動類
1 package com.zyj.application; 2 3 import com.zyj.entity.Persion; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 /** 8 * @author zyj 9 * @Package com.zyj.application 10 */ 11 /* 12 * ????Sping IOC是什麼時候創建的對象?? 13 *在讀取spring的配置文件的時候就已經創建了java對象 14 * */ 15 public class MyApplication { 16 public static void main(String[] args) { 17 /** 18 * ApplicationContext是IOC容器的入口類,要獲取ioc容器中的對象必須常見該類 19 * ClassPathXmlApplicationContext該類是讀取spring的xml配置文件的 20 */ 21 ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); 22 //獲取ioc容器中的具體對象,需要強制類型轉換 23 // Persion persion = (Persion)context.getBean("persion"); 24 //獲取ioc容器中的對象,不需要強制類型轉換 25 Persion persion = context.getBean("persion",Persion.class); 26 System.out.println(persion); 27 } 28 }
5.執行結果
6.想看下java對象是通過spring什麼時候創建的嗎…….修改測試啟動類MyApplication.java
1 package com.zyj.application; 2 3 import com.zyj.entity.Persion; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 /** 8 * @author zyj 9 * @Package com.zyj.application 10 */ 11 /* 12 * ????Sping IOC是什麼時候創建的對象?? 13 *在讀取spring的配置文件的時候就已經創建了java對象 14 * */ 15 public class MyApplication { 16 public static void main(String[] args) { 17 /** 18 * ApplicationContext是IOC容器的入口類,要獲取ioc容器中的對象必須常見該類 19 * ClassPathXmlApplicationContext該類是讀取spring的xml配置文件的 20 */ 21 ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); 22 //獲取ioc容器中的具體對象,需要強制類型轉換 23 // Persion persion = (Persion)context.getBean("persion"); 24 //獲取ioc容器中的對象,不需要強制類型轉換 25 /*Persion persion = context.getBean("persion",Persion.class); 26 System.out.println(persion);*/ 27 } 28 }
7.執行結果:
由此可看出:在讀取spring的配置文件,並沒有使用該對象的時候,就已經創建完成了對象。
以上~謝謝!