Spring1(想要了解Spring的IoC是什麼?看這篇文章就夠了! 帶你完成第一個Spring程序)

Spring

(一)概述:

1.什麼是Spring?

Spring是一個從實際開發中抽取出來的框架,因此它完成了大量開發中的通用步驟,留給開發者的僅僅是與特定應用相關的部分,從而大大提高了企業應用的開發效率。Spring使每個人都可以更快,更輕鬆,更安全地進行Java編程;Spring對速度,簡單性和生產率的關注使其成爲世界上最受歡迎的 Java框架。
Spring框架由 Rod Johnson 開發,他是悉尼大學的博士,然而他的專業不是計算機,而是音樂學,所以我們可以用心感受Spring中的優雅和魅力;2004年3月24日,發佈了1.0正式版。
在這裏插入圖片描述

2.Spring官網

  • https://spring.io

從官網我們可以找到Spring各類的參考文獻和API文檔:
在這裏插入圖片描述

3.Spring的優點

  • 低侵入式設計,代碼的污染極低;
  • 獨立於各種應用服務器,基於Spring框架的應用,可以真正實現Write Once,Run Anywhere的承諾;
  • Spring的IoC容器降低了業務對象替換的複雜性,提高了組件之間的解耦;
  • Spring的AOP支持允許將一些通用任務如安全、事務、日誌等進行集中式管理,從而提供了更好的複用;
  • Spring的ORM和DAO提供了與第三方持久層框架的良好整合,並簡化了底層的數據庫訪問;
  • Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可自由選用Spring框架的部分或全部。

(二)剖析IOC/DI:

1.什麼是IoC/DI?

它Spring的核心技術之一,IoC(Inversion of Control)控制反轉,是一種設計思想,DI(Dependency Injection)依賴注入,是實現IoC的一種方法,後來 Martine Fowler 爲這種方式起了另一個名稱即DI;在此過程中,對象僅通過構造函數參數,工廠方法的參數或在構造或從工廠方法返回後在對象實例上設置的屬性來定義其依賴項(即,與它們一起使用的其他對象)。
控制反轉是一種通過描述(XML或註解)並通過第三方去生產或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入。

2.看圖說話

  1. 在沒有IoC的程序中 , 我們使用面向對象編程 , 對象的創建與對象間的依賴關係完全硬編碼在程序中,對象的創建由程序自己控制,底層的實現都是由N個對象組成的,所有的對象通過彼此的合作,最終實現系統的業務邏輯:(存在耦合)
    在這裏插入圖片描述
  2. IoC容器將全部對象的控制權全部交由自己這個“第三方”,把複雜系統分解成相互合作的對象,這些對象類通過封裝以後,內部實現對外部是透明的,從而降低了解決問題的複雜度,而且可以靈活地被重用和擴展。藉助於“第三方”(IoC容器)實現具有依賴關係的對象之間的解耦,即控制反轉後將對象的創建轉移給第三方:
    在這裏插入圖片描述
  3. 解耦後,拿掉IoC容器後的系統,就是我們要實現整個系統所需要完成的全部內容。這時候,A、B、C、D這4個對象之間已經沒有了耦合關係,彼此毫無聯繫,這樣,當你在實現A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關係已經降低到了最低程度。所以,對於系統開發而言,這將是一件多麼美好的事情,參與開發的每一成員只要實現自己的類就可以了,跟其他就沒有任何關係了。
    在這裏插入圖片描述

3.通過代碼分析實現IoC

  1. 我們原來的方式:
  • Dao層

定義接口:

public interface UserDao {
    public void getUser();
}

定義接口的實現類:

public class UserDaoImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("獲取用戶數據");
    }
}
  • Service層

定義Service接口:

public interface UserService {
    public void getUser();
}

定義Service的實現類:(在這裏實現Dao層的方法)

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();
    
    @Override
    public void getUser() {
        userDao.getUser();
    }
}

測試:
用戶調用的是業務層的實現類,用戶不需要接觸Dao層

@Test
public void test(){

    UserService service = new UserServiceImpl();
    service.getUser();
    
}
//結果:獲取用戶數據
  1. 新的需求:現在需要再增加一個實現類:(UserDaoMySqlImpl)
public class UserDaoMySqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("MySql獲取用戶數據");
    }
}

此時如果我們需要使用這個實現類,就需要去Service層的實現類裏面修改代碼,從而得以實現:

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoMySqlImpl ();
    
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// 結果:MySql獲取用戶數據
  1. 發現問題:
    假設我們如果再增加新的實現類,又需要去Service實現類裏面修改代碼,從而得以實現,這種方式就不適用了,每次變動,都需要修改大量代碼,存在很大的耦合性,牽一髮而動全身
  2. 解決問題:
    我們可以在需要用的地方 , 不去實現它 , 而是留出一個接口 , 利用set實現:
public class UserServiceImpl implements UserService {

    private UserDao userDao;
    // set實現動態值的注入
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
    
    @Override
    public void getUser() {
        userDao.getUser();
    }
}

對應的測試類:

@Test
    public void test(){
        UserServiceImpl service = new UserServiceImpl();
        //實現UserDaoMySqlImpl
        service.setUserDao(new UserDaoMySqlImpl());
        service.getUser();
		//實現新的類
        service.setUserDao(new UserDaoMySqlImpl2());
        service.getUser();
        /*
        service.setUserDao(new xxxx());
        service.getUser();
        */
    }

總結:
以前所有東西都是由程序去控制創建,而現在是由我們自行控制創建對象,把主動權交給了調用者;程序不用去管怎麼創建、怎麼實現了,它只負責提供一個接口;這種思想,從本質上解決了問題,我們程序員不用去管理對象的創建了,更多的去關注業務的實現,耦合性大大降低 ,這也就是IOC的原型。

(三)創建一個Spring程序

  1. 通過依賴,導入Spring相關的jar包:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.3.RELEASE</version>
</dependency>
  1. 編寫代碼:
  • 編寫一個實體類
public class Hello {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("Hello,"+ name );
    }
}
  • 將實體類注入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">
    <!-- bean就是java對象 , 由Spring創建和管理 -->
    <bean id="hello" class="com.chen.pojo.Hello">
    <!-- name就是屬性, value就是賦的值 -->
        <property name="name" value="Spring"/>
    </bean>

</beans>
  • 測試:
public void testHelloSpring(){
        //解析你的.xml文件 , 生成管理相應的Bean對象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //getBean : 參數即爲spring配置文件中bean的id .
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
    }
//結果:Hello,Spring

總結:
hello 對象是由Spring創建的;
hello 對象的屬性是由Spring容器設置的;
想要實現不同的操作,只需要在xml配置文件中進行修改,所謂的IoC即: 對象由 Spring 來創建、管理 、裝配 。

//下篇再見…謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章