路漫漫其修遠兮,吾將上下而求索
0. Spring是啥
Spring其實就是指的Spring Framework,它是一個框架,官方對其描述是如下:
Spring Framework為現代基于Java的企業應用程式提供了一個全面的編程和配置模型,Spring的一個關鍵元素是應用程式級別的基礎設施支持,主要專注于企業應用程式的“管道”,以便團隊可以專注于應用程式級的業務邏輯,而無需與特定部署環境產生不必要的聯系
我個人對于以上的理解是,Spring Framework就是一套框架,使用它來寫代碼,我們就可以更專注于程式的業務邏輯,而對于業務之間的依賴,可以通過Spring Framework幫我們統一管理,其中的框架包含了:IOC(控制反轉)、AOP(切面編程)、事務、資料系結、驗證等等(https://docs.spring.io/spring-framework/docs/current/reference/html/)
1. Spring IOC是啥
對于Spring Framework有了一點概念之后,我們需要知道它主要是幫我們做了些什么,如何幫助我們簡化企業應用程式開發的呢,那就不得不提其最為核心的Spring IOC了,先看看官方對于IOC的描述
IOC(Inversion of Control 控制反轉)也稱為依賴注入(DI),這是一個程序,其中物件僅通過建構式引數、工廠方法的引數或者在物件實體被構造或者從工廠回傳后再物件實體上設定的屬性來定義他們的依賴項(即它們需要用到哪些物件),然后容器在創建bean時注入這些依賴項,這個程序基本上是bean本身的逆程序(因此得名,控制反轉),
也就是說,我們之前需要一個物件時,需要自己在代碼中創建,即通過new一個物件的方式,但是現在我們只需要在Spring IOC中配置好我們哪些物件依賴了哪些物件,這樣Spring容器在創建bean(也就是物件)的時候,就會幫我們注入所依賴的物件,我們就不用在代碼中去new創建了,只需要在Spring 中配置就可以了,其實它就相當于一個大工廠,對于在萬物皆物件的Java中,有了Spring之后,我們就不用擔心物件之間的復雜依賴關系了,所有物件的創建和維護都由Spring容器來管理,這樣也可以降低程式的耦合性,
2. Spring環境搭建
實踐是檢驗真理的唯一標準 ,好了,大概了解了理論之后,就來動手實踐一下吧,
2.1 新建一個Maven專案
首先創建一個普通maven專案,并在pom檔案中,添加好spring所需依賴,這里有一些依賴包并不是必要的,但為了以后方便使用,也直接先匯入到依賴中來,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
?
<groupId>top.xiateman</groupId>
<artifactId>spring-ioc</artifactId>
<version>1.0-SNAPSHOT</version>
?
<properties>
<org.springframework.version>5.3.10</org.springframework.version>
<commons-logging.version>1.2</commons-logging.version>
<junit.version>4.12</junit.version>
</properties>
?
<dependencies>
<!-- Spring核心依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- Spring beans包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- Spring 容器包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
?
<!-- junit 單元測驗依耐 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
?
?
</project>
確定好所有依賴都導進來之后,就可以繼續撰寫代碼了

2.2 傳統代碼撰寫
我們設想一個場景,就是用戶去買水果,它們分別需要對應的是 買水果的人(用戶),賣水果的人(業務層),水果(持久化層)

我們先寫一個水果類的介面(面向介面編程嘛)
/**
* Fruit.java
*/
public interface Fruit {
?
/**
* 獲取水果的方法
*/
public void get();
?
}
接著撰寫水果的實作類,蘋果、橘子、香蕉
/**
* Apple.java
*/
public class Apple implements Fruit{
public void get() {
System.out.println("蘋果");
}
}
/**
* Orange.java
*/
public class Orange implements Fruit{
public void get() {
System.out.println("橙子");
}
}
/**
* Banana.java
*/
public class Banana implements Fruit{
public void get() {
System.out.println("香蕉");
}
}
然后再撰寫一個業務類,來實作具體的獲取水果的業務
/**
* UserService.java
*/
public class UserService {
private Fruit fruit = new Apple();
public void getFruit(){
fruit.get();
}
}
用戶類
/**
* User.java
*/
public class User {
?
public static void main(String[] args) {
UserService userService = new UserService();
userService.getFruit();
}
}
以上的情況就是我們傳統的方式,可以看到業務層中對于Fruit的實作類產生了嚴重的耦合性,如果現在用戶想獲取一個Orange,則我們也需要直接修改業務中的代碼,這不符合開閉原則,而且如果涉及的業務比較多的話,直接更改代碼也會帶來其他的風險與成本,所以我們需要把業務中的具體物件控制,交給用戶來定義,我們可以修改一下業務類
public class UserService {
private Fruit fruit;
//通過set方法來“注入”具體的水果類
public void setFruit(Fruit fruit){
this.fruit = fruit;
}
public void getFruit(){
fruit.get();
}
}
具體的水果類,在用戶呼叫的時候,由用戶來控制實作
public class User {
?
public static void main(String[] args) {
UserService userService = new UserService();
//注入具體的水果實作類
userService.setFruit(new Orange());
userService.getFruit();
}
?
}
這樣一來,我們的業務類就無需再改動了,用戶需要獲取什么水果,由它來自己定義,用戶來掌控具體實作的主動權,而我們在業務中只需要提供這些選擇給予用戶即可,前后的改動主要體現在對于業務層來說,之后的代碼無需改動,因為我們已經把主動權交給了用戶,用戶想要什么,它就“注入”什么,

其實我們上面所講的,實際上就是IOC的核心思想,也就是所謂的控制反轉,
2.3 SpringIOC代碼撰寫
現在我們來體驗一下通過Spring IOC實際的流程和實作效果
首先先在resource目錄下創建一個applicationContext.xml檔案,用于配置Spring容器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
//將水果類,業務類都注冊到Spring容器中,交由Spring來管理和創建
<bean id="apple" class="top.xiateman.service.Apple"></bean>
<bean id="orange" class="top.xiateman.service.Orange"></bean>
<bean id="banana" class="top.xiateman.service.Banana"></bean>
<bean id="userService" class="top.xiateman.service.UserService">
//這里相當于為setFruit()方法中,注入一個banana的物件,ref表示參考容器中id為banana的bean
<property name="fruit" ref="banana"></property>
</bean>
</beans>
然后我們再通過直接中IOC容器中來獲取到我們所需要的物件實體
public class User {
?
public static void main(String[] args) {
//Spring容器加載組態檔
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取我們所需要的bean(物件實體)
UserService userService = context.getBean("userService",UserService.class);
userService.getFruit();
}
?
}
通過以上我們可以了解到,現在我們已經是將主要的控制權交給了Spring IOC容器,我們先在組態檔中(注冊)配置好我們所撰寫好的物件,用戶則只需要直接從Spring 容器中獲取所需的物件實體即可,如果用戶想更改獲取的實體物件,只需在組態檔中修改對應的配置,而無需再去修改代碼,這樣就大大減少了代碼之間的耦合性,可以只通過修改組態檔的方式,來獲取到不同的具體實作,

2.4 Spring IOC的好處
通過上面的例子我們可以體會到,在沒有不通過Spring的時候,我們物件之間的耦合性比較大,物件之間產生了強依賴,一旦需求有所變動的話,則會牽涉到很多代碼,這無疑會大大增加我們的作業量,每一次都需要去更改代碼,而使用了SpringIOC之后,我們則將所有的物件交由Spring來管理控制,我們物件之間的依賴需要的具體實作則只需要在組態檔中配置即可,從而無需去更改代碼了,

3. 總結
Spring IOC的本質就是將控制權從程式代碼中剝離開來,業務的具體實作不再是直接從代碼中來實作,而是通過SpringIOC這個第三方的容器,來幫我們管理和創建我們業務中所需要的具體物件實體,這樣就大大減低代碼中,物件之間依賴的耦合度,
參考文章:
https://blog.csdn.net/qq_37084904/article/details/108633797
https://www.zhihu.com/question/23277575/answer/1073420019
文章內容由個人理解所撰寫,存在不足之處,僅供參考,
多讀多看多寫,,,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/306552.html
標籤:其他
