Spring框架(二)——IOC的本質分析、HelloSpring

1.IOC本質

控制反轉IoC(Inversion of Control),是一種設計思想,DI(依賴注入)是實現IoC的一種方法,也有人認爲DI只是IoC的另一種說法。沒有IoC的程序中 , 我們使用面向對象編程 , 對象的創建與對象間的依賴關係完全硬編碼在程序中,對象的創建由程序自己控制,控制反轉後將對象的創建轉移給第三方,個人認爲所謂控制反轉就是:獲得依賴對象的方式反轉了。

採用XML方式配置Bean的時候,Bean的定義信息是和實現分離的,而採用註解的方式可以把兩者合爲一體,Bean的定義信息直接以註解的形式定義在實現類中,從而達到了零配置的目的。

控制反轉是一種通過描述(XML或註解)並通過第三方去生產或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)。

2.IOC理論推導

2.1普通的方式

  • 先寫一個UserMapper接口
package com.zj.Dao;

public interface UserMapper {
    public void getUser();
}

  • 再去寫Dao的實現類
package com.zj.Dao;

public class UserMapperImpl implements UserMapper {
    public void getUser() {
        System.out.println("獲取數據");
    }
}


  • 然後去寫UserService的接口
package com.zj.service;

public interface UserService {
   public void getUser();
}

  • 最後寫Service的實現類
package com.zj.service;

import com.zj.Dao.UserMapper;
import com.zj.Dao.UserMapperImpl;

public class UserServiceImpl implements UserService {

   private UserMapper userMapper =new UserMapperImpl();
   
   public void getUser() {
     userMapper.getUser();
   }
}
}

  • 測試一下
public class MyTest {
   @Test
   public void test(){
       UserServiceImpl service = new UserServiceImpl();
      service.setUserMapper(new UserMapperImpl());
       service.getUser();
}
}
  • 把UserMapper的實現類增加一個 .
public class UserMapperMySqlImpl implements UserMapper {
   public void getUser() {
       System.out.println("MySQL數據");
   }
}
  • 緊接着我們要去使用MySQL的話 , 我們就需要去service實現類裏面修改對應的實現 .
public class UserServiceImpl implements UserService {

    private UserMapper userMapper =new UserMapperMySqlImpl();
    
    public void getUser() {
      userMapper.getUser();
    }
}
}
  • 在假設, 我們再增加一個UserMapper的實現類 .
public class UserMapperOracleImpl implements UserMapper {
   public void getUser() {
       System.out.println("OracleI獲取數據");
   }
}

在這裏插入圖片描述
那麼我們要使用Oracle , 又需要去service實現類裏面修改對應的實現 . 假設我們的這種需求非常大 , 這種方式就根本不適用了, 甚至反人類對吧 , 每次變動 , 都需要修改大量代碼 . 這種設計的耦合性太高了, 牽一髮而動全身
那我們如何去解決呢 ?

2.2 修改後的方式

我們可以在需要用到他的地方 , 不去實現它 , 而是留出一個接口 , 利用set , 我們去代碼裏修改如下 .

public class UserServiceImpl implements UserService {

    private UserMapper userMapper;


    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public void getUser() {
      userMapper.getUser();
    }
}

  • 在測試下
public class MyTest {
    @Test
    public void test(){
        UserServiceImpl service = new UserServiceImpl();
        /*service.setUserMapper(new UserMapperImpl());
        service.getUser();*/
        service.setUserMapper(new UserMapperMySqlImpl());
        service.getUser();

    }

在這裏插入圖片描述

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

3、HelloSpring

1. 導入Spring相關jar包

注 : spring 需要導入commons-logging進行日誌記錄 . 我們利用maven , 他會自動下載對應的依賴項 .

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.10.RELEASE</version>
</dependency>

2. 編寫相關代碼

2.1編寫一個Hello實體類

package com.zj.pojo;

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 );
    }

    @Override
    public String toString() {
        return "Hello{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.2 寫編寫我們的spring文件 , 這裏我們命名爲applicationContext.xml

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="hello" class="com.zj.pojo.Hello">
        <property name="name" value="spring"/>
    </bean>
  
</beans>

2.3 我們可以去進行測試了 .

@Test
    public void test1(){
    ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
    //getBean : 參數即爲spring配置文件中bean的id .
    Hello hello = (Hello) context.getBean("hello");
    hello.show();
}

思考問題

  • Hello 對象是誰創建的 ?

    hello 對象是由Spring創建的

  • Hello 對象的屬性是怎麼設置的 ?

    hello 對象的屬性是由Spring容器設置的 ,

這個過程就叫控制反轉 :

控制 : 誰來控制對象的創建 , 傳統應用程序的對象是由程序本身控制創建的 , 使用Spring後 , 對象是由Spring來創建的 .

反轉 : 程序本身不創建對象 , 而變成被動的接收對象 .

依賴注入 : 就是利用set方法來進行注入的.

IOC是一種編程思想 , 由主動的編程變成被動的接收 .

可以通過newClassPathXmlApplicationContext去瀏覽一下底層源碼 .

OK , 到了現在 , 我們徹底不用再程序中去改動了 , 要實現不同的操作 , 只需要在xml配置文件中進行修改 , 所謂的IOC,一句話搞定 : 對象由Spring 來創建 , 管理 , 裝配 !

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