Spring淺入淺出——不吹牛逼不裝逼

  • 2019 年 10 月 3 日
  • 筆記

Spring淺入淺出——不吹牛逼不裝逼

前言:

今天決定要開始總結框架了,雖然以前總結過兩篇,但是思維是變化的,而且也沒有什麼規定說總結過的東西就不能再總結了,是吧。這次總結我命名為淺入淺出,主要在於理解框架核心,輕鬆愉快使用框架。

 

核心思想

我們都學了面向對象,在生活中,當人們需要一件東西時,第一反應就是找東西,例如想吃麵包,現在有兩種情況,第一種是沒有麵包店,第二種是有麵包店。第一種情況就是我們之前一直遇到的情況,在沒有麵包店的情況下,最直觀的做法可能就是你按照自己的口味製作麵包,也就是一個麵包需要主動製作,誰想吃了就自己New。而我主要說的是第二種情況,就是有麵包店,你想吃麵包的時候找到麵包店,把自己的口味告訴店家,店家就可以給你做符合你口味的麵包了。注意:你並沒有製作麵包,而是由店家製作,但是完全符合你的口味。

 

這是一個很生活的例子,大家都明白,但這裡包含了Spring中很重要的思想——控制反轉,就是把製作麵包的主動權交給店家,麵包就是對象,店家相當於一個大容器,你想要什麼對象,就讓大容器去給你生產,這就是控制反轉思想。

 

再詳細點,當某個Java對象(調用者,例如你)需要調用另一個Java對象(被調用者,即被依賴對象,例如麵包)時,在傳統編程模式下,調用者通常會採用“New 被調用者”的代碼方式來創建對象(例如你自己製作麵包)。這種方式會增加調用者與被調用者之間的耦合性,不利於後期代碼的升級和維護。

 

當Spring框架出現後,對象的實例不再由調用者來創建,而是由 Spring容器(例如麵包店)來創建。Spring容器會負責控制程序之間的關係(例如麵包店負責控制你與麵包的關係),而不是由調用者的程序代碼直接控制。這樣,控制權由調用者轉移到Spring容器,控制權發生了反轉,這就是Spring的控制反轉。

 

在之前,我們需要用構造方法或者set()方法給一些成員變量賦值,從Spring容器角度來看,Spring容器負責將被依賴對象賦值給調用者的成員變量,相當於為調用者注入它所依賴的實例,這就是Spring的依賴注入。

 

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

 

 

Spring IoC容器

看完上面所述,我們知道實現控制反轉的是Spring IoC容器。Spring IoC容器的設計主要是基於BeanFactory和ApplicationContext兩個接口。

 

先說BeanFactory,它提供了完整的IoC服務支持,是一個管理Bean的工廠,主要負責初始化各種Bean。BeanFactory接口有多個實現類,其中比較常用的是org.springframework.beans.factory.xml.XmlBeanFactory,該類會根據XML配置文件中的定義來裝配Bean.由於BeanFactory實例加載Spring配置文件在實際開發中並不多見,只需了解即可,我也不過多解說了。

 

再說ApplicationContext,它是BeanFactory的子接口,也稱為應用上下文,ApplicationContext接口除了包含BeanFactory的所有功能以外,還添加了對國際化、資源訪問、事件傳播等內容的支持。創建ApplicationContext接口實例通常有三種方法:

1、 通過ClassPathXmlApplicationContext創建

2、 通過FileSystemXmlApplicatonContext創建

3、 通過Web服務器實例化ApplicationContext容器

 

作為一個初學者,我覺得先會用第一種就可以了,所以我主要解說第一種,別的等你自己入門後自己看,我只做引導。

 

ClassPathXmlApplicationContext將從類路徑目錄(src根目錄)中尋找指定的XML配置文件,如下代碼:

 

public class Test {      public static void main(String[] args) {          //初始化SPring容器,加載配置文件          ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml");          //通過容器獲得test實例          TestDao tt = (TestDao) appCon.getBean("test");          tt.sayHello();      }  }      

  

 

 

依賴注入的類型

在Spring中實現IoC容器的方法是依賴注入,依賴注入的作用是在使用Spring框架創建對象時動態地將其所依賴的對象(例如屬性值)注入Bean組件中,Spring框架的依賴注入通常有兩種實現方式,一種是使用構造方法注入,另一種是使用屬性的setter方法注入。具體且看實例演示

 

 

實例演示

一、在pom.xml中導入相應模塊

<dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.11</version>      <scope>test</scope>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>jstl</artifactId>      <version>1.2</version>    </dependency>    <dependency>      <groupId>commons-logging</groupId>      <artifactId>commons-logging</artifactId>      <version>1.2</version>    </dependency>      <!--spring核心依賴-->    <dependency>      <groupId>mysql</groupId>      <artifactId>mysql-connector-java</artifactId>      <version>5.1.38</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aop</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-jdbc</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-expression</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-tx</artifactId>      <version>5.1.5.RELEASE</version>    </dependency>    </dependencies>  

  

 

 

二、創建TestDao

package com.my.dao;    public interface TestDao {      public void sayHello();  }  

  

 

三、創建TestDaoImpl

package com.my.dao.impl;    import com.my.dao.TestDao;    public class TestDaoImpl implements TestDao {      @Override      public void sayHello() {          System.out.println("Hello Spring!!!");      }  }      

  

四、創建spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:context="http://www.springframework.org/schema/context"         xmlns:tx="http://www.springframework.org/schema/tx"         xmlns:mvc="http://www.springframework.org/schema/mvc"         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         http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx.xsd         http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc.xsd          ">      <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/>  </beans>      

  

五、測試Test

package com.my.test;    import com.my.dao.TestDao;  import com.my.dao.impl.TestDaoImpl;  import com.my.service.TestService;  import org.springframework.context.ApplicationContext;  import org.springframework.context.support.ClassPathXmlApplicationContext;    public class Test {      public static void main(String[] args) {          //調用者自己創建對象          TestDao testDao = new TestDaoImpl();          testDao.sayHello();            //初始化SPring容器,加載配置文件          ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml");          //通過容器獲得test實例          TestDao tt = (TestDao) appCon.getBean("testDIDao");          tt.sayHello();        }  }  

  

六、測試結果

 

 

七、創建TestService

package com.my.service;    public interface TestService {      public void sayHello();  }  

  

 

八、創建TestServiceImpl

package com.my.service.impl;    import com.my.dao.TestDao;  import com.my.service.TestService;    public class TestServiceImpl implements TestService {      private TestDao testDao;  //構造方法,用於實現依賴注入接口對象TestDao      public TestServiceImpl(TestDao testDao) {          this.testDao = testDao;      }        @Override      public void sayHello() {          testDao.sayHello();      }  }      

  

九、在spring-config.xml中注入

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:context="http://www.springframework.org/schema/context"         xmlns:tx="http://www.springframework.org/schema/tx"         xmlns:mvc="http://www.springframework.org/schema/mvc"         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         http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx.xsd         http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc.xsd          ">      <!--將指定類TestDaoImpl配置給Spring,讓Spring創建其實例-->      <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/>      <!--使用構造方法注入-->      <bean id="testDIService" class="com.my.service.impl.TestServiceImpl" >          <!--將TestDIDao注入到TestDIServiceImpl類的屬性testDao上-->          <constructor-arg index="0" ref="testDIDao"/>      </bean>  </beans>      

  

十、測試Test

package com.my.test;    import com.my.dao.TestDao;  import com.my.dao.impl.TestDaoImpl;  import com.my.service.TestService;  import org.springframework.context.ApplicationContext;  import org.springframework.context.support.ClassPathXmlApplicationContext;    public class Test {      public static void main(String[] args) {          //調用者自己創建對象          TestDao testDao = new TestDaoImpl();          testDao.sayHello();            //初始化SPring容器,加載配置文件          ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml");          //通過容器獲得test實例          TestDao tt = (TestDao) appCon.getBean("testDIDao");          tt.sayHello();          //通過容器獲取TestService實例,測試構造方法注入          TestService testService =(TestService) appCon.getBean("testDIService");          testService.sayHello();      }  }  

  

 

十一、測試結果

 

 

十二、使用屬性的setter方法注入

package com.my.service.impl;    import com.my.dao.TestDao;  import com.my.service.TestService;    public class TestServiceImpl implements TestService {      private TestDao testDao;      //添加testDao屬性的setter方法,用於實現依賴注入      public void setTestDao(TestDao testDao){          this.testDao=testDao;      }        @Override      public void sayHello() {          testDao.sayHello();      }  }  

  

 

十三、在spring-config.xml中注入

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:context="http://www.springframework.org/schema/context"         xmlns:tx="http://www.springframework.org/schema/tx"         xmlns:mvc="http://www.springframework.org/schema/mvc"         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         http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx.xsd         http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc.xsd          ">      <!--將指定類TestDaoImpl配置給Spring,讓Spring創建其實例-->      <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/>        <!--使用setter方法注入-->      <bean id="testDIService" class="com.my.service.impl.TestServiceImpl">          <!--調用TestDIServiceImpl類的setter方法,將TestDao注入到TestServiceImpl類的屬性testDao上-->          <property name="testDao" ref="testDIDao"></property>      </bean>  </beans>      

  

十四、測試Test

package com.my.test;    import com.my.dao.TestDao;  import com.my.dao.impl.TestDaoImpl;  import com.my.service.TestService;  import org.springframework.context.ApplicationContext;  import org.springframework.context.support.ClassPathXmlApplicationContext;    public class Test {      public static void main(String[] args) {          //調用者自己創建對象          TestDao testDao = new TestDaoImpl();          testDao.sayHello();            //初始化SPring容器,加載配置文件          ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml");          //通過容器獲得test實例          TestDao tt = (TestDao) appCon.getBean("testDIDao");          tt.sayHello();          //通過容器獲取TestService實例,測試setter方法注入          TestService testService =(TestService) appCon.getBean("testDIService");          testService.sayHello();      }  }  

  

 

十五、測試結果

 

 

 

 

注入說明

在Src根目錄下創建Spring配置文件spring-config.xml(文件名隨意,注意後綴.xml)。在配置文件中,constructor-arg元素用於定義類構造方法的參數,index用於定義參數的位置,ref指定某個實例的引用,如果參數是常量值,ref由value代替。

 

特別鏈接

看完此篇後你覺得理解了,可以看看我以前寫的這幾篇博客,會有幫助的

沒有無緣無故的編程https://www.cnblogs.com/zyx110/p/11297822.html

路過別錯過https://www.cnblogs.com/zyx110/p/11271820.html

spring框架知多少https://www.cnblogs.com/zyx110/p/11022891.html

用IDEA開發Spring程序https://www.cnblogs.com/zyx110/p/11023218.html

 

 

結束語

此篇Spring淺入淺出到此結束,作此篇是為了讓初學者放下心理枷鎖,先理解,其實挺好理解的,等你有信心後自己學習就可以了,希望能對一些朋友有所幫助,加油。

 

 

 

*****************************************************************************************************

我的博客園地址:https://www.cnblogs.com/zyx110/

轉載請說明出處

我不能保證我所說的都是對的,但我能保證每一篇都是用心去寫的,我始終認同“分享的越多,你的價值增值越大”,歡迎大家關注我的技術分享“Java匹馬行天下”和學習心得分享“匹馬行天下”,在分享中進步,越努力越幸運,人生贏在轉折處,改變從現在開始!

支持我的朋友們記得點波推薦哦,您的肯定就是我前進的動力。