Spring---學習第一天(Spring概述+IOC+Bean作用範圍,生命週期+創建Bean+依賴注入)

Spring概述

什麼是Spring?

Spring是目前比較火的一個全棧輕量級的開源框架,以ICO(Inverse Of Control 即控制反轉)和AOP(Aspect Oriented Programming 即面向切面編程)爲核心,以能夠黏合各大第三方框架著稱,是現在Java EE企業中應用最多的框架之一。

Spring的發展

Spring的發展與EJB(Enterprise Java Beans)的發展離不開關係,它的出現可以說是爲了解決EJB在J2EE中的開發的問題。

1997 年 IBM 提出了 EJB 的思想
1998 年, SUN 制定開發標準規範 EJB1.0
Rod Johnson(spring 之父)深入研究了EJB在實際開發中存在的問題,於2017 年 9 月份發佈了 spring 的最新版本 spring 5.0 通用版(GA)

Spring的優點

Spring在實際開發中具有以下的優點:

方便解耦,簡化開發 通過IOC機制在很大程度上削減了程序的耦合。
AOP 編程的支持 可以彌補傳統的OOP編程的短板
聲明式事務的支持 通過聲明式方式靈活的進行事務的管理
方便程序的測試 用非容器依賴的編程方式進行幾乎所有的測試工作
方便集成各種優秀框架 提供了對各種優秀框架的直接支持
降低 JavaEE API 的使用難度 Spring 對 JavaEE API進行了封裝,使這些 API 的使用難度大爲降低

Spring的體系結構

這是從spring官網下載的圖片
這是從spring官網下載的圖片

Spring IOC

什麼是耦合?

耦合是對模塊間關聯程度的度量,是指模塊之間的依賴關係,包括控制關係、調用關係、數據傳遞關係。模塊間聯繫越多,其耦合性越強,同時表明其獨立性越差,在軟件工程中,耦合指的就是就是對象之間的依賴性對象之間的耦合越高,維護成本越高。因此對象的設計應使類和構件之間的耦合最小。

什麼是Spring IOC?

IOC是spring的一種核心機制,全稱Inversion of Control即控制反轉,它將對象創建的工作交給了框架控制,取代了傳統的對象內部控制,示圖如下:

傳統模式
在這裏插入圖片描述

IOC模式
在這裏插入圖片描述

SpringIOC的作用

削減計算機程序的耦合(解除我們代碼中的依賴關係),但是隻能做到削減,不能做到消除。 實際開發中應該做到:編譯期不依賴,運行時才依賴。

解耦的思路:

  • 第一步:使用反射來創建對象,而避免使用new關鍵字。
  • 第二步:通過讀取配置文件來獲取要創建的對象全限定類名

Spring IOC的核心容器(ApplicationContext+BeanFactory)

在這裏插入圖片描述

BeanFactory和Application的區別:

聯繫:

BeanFactory 是 Spring 容器中的頂層接口。
ApplicationContext 是它的子接口。

區別:

ApplicationContext:只要一讀取配置文件,默認情況下就會創建對象。
BeanFactory:什麼使用什麼時候創建對象

ApplicationContext的三個常用實現子類
  • ClassPathXmlApplicationContext:它可以加載類路徑下的配置文件,但配置文件必須在類路徑下。不然加載不了,較爲常用。
  • FileSystemXmlApplicationContext:它可以加載磁盤任意路徑下的配置文件,但需要全路徑。
  • AnnotationConfigApplicationContext:它是用於讀取註解創建容器的。
用核心容器創建Bean對象:

1.創建核心容器關聯相應的配置文件
2.使用核心容器根據id獲取對象

1.BeanFactory
    Resource resource=new ClassPathResource("bean.xml");
    BeanFactory beanFactory=new XmlBeanFactory(resource);
    AccoutService accoutService = (AccoutService)beanFactory.getBean("accoutService");
    AccoutService accoutService1 = (AccoutService)beanFactory.getBean("accoutService");
    System.out.println(accoutService==accoutService1);
2.ApplicationContext
	ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
    AccoutService accoutService = (AccoutService)ac.getBean("accoutService");
    AccoutDao dao=(AccoutDao)ac.getBean("accoutDao",AccoutDao.class);
    System.out.println(accoutService);
    System.out.println(dao);

Spring實例化Bean的三種方式

1.使用默認構造函數創建

在spring的配置文件中使用bean標籤,配以id和class屬性之後,且沒有其他屬性和標籤時,採用的就是默認構造函數創建bean對象,此時如果類中沒有默認構造函數,則對象無法創建。

 <bean id="accountService" class="com.gzgs.service.impl.AccountServiceImpl"></bean>

2.使用工廠的模式創建

<bean id="inStanceFactory" class="com.gzgs.factory.InstanceFactory"></bean>
<bean id="accoutService" factory-bean="inStanceFactory" factory-method="getAccountService"></bean>

3.使用工廠中的靜態方法創建對象

<bean id="accountService" class="com.gzs.factory.StaticFactory" factory-method="getAccountService"></bean>

Spring Bean

Spring Bean的作用範圍

bean標籤的scope屬性:

作用:用於指定bean的作用範圍

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"></bean>

scope屬性取值:

singleton:單例的(默認)
prototype:多例的
request:作用於web應用的請求範圍
session:作用於web應用的會話範圍
global-session:作用於集羣環境的會話範圍(全局會話範圍),當不是集羣環境時,它就是session
常用的就是單例的和多例的

Spring Bean的生命週期

單例對象

出生:當容器創建時對象出生
活着:只要容器還在,對象一直活着
死亡:容器銷燬,對象消亡
總結:單例對象的生命週期和容器相同

多例對象

出生:當我們使用對象時spring框架爲我們創建
活着:對象只要是在使用過程中就一直活着。
死亡:當對象長時間不用,且沒有別的對象引用時,由Java的垃圾回收器回收

Spring的依賴注入

依賴注入(Dependency Injection)在當前類需要用到其他類的對象,由spring爲我們提供,我們只需要在配置文件中說明依賴關係的維護,這就是依賴注入。

依賴注入能實現的入住類型

  • 基本類型和String
  • 其他在註解配置過或在配置文件中的bean類型
  • 複雜類型/集合類型

依賴注入的方式

  • 使用構造函數注入
  • 使用set方法注入
  • 使用註解注入

使用構造函數注入

使用的標籤:constructor-arg
標籤出現的位置:bean標籤的內部
標籤中的屬性

type:用於指定要注入的數據的數據類型,該數據類型也是構造函數中某個或某些參數的類型
index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值。索引的位置是從0開始
name:用於指定給構造函數中指定名稱的參數賦值
value:用於提供基本類型和String類型的數據
ref:用於指定其他的bean類型數據。它指的就是在spring的Ioc核心容器中出現過的bean對象

  • 優勢:
    在獲取bean對象時,注入數據是必須的操作,否則對象無法創建成功。
  • 弊端:
    改變了bean對象的實例化方式,使我們在創建對象時,如果用不到這些數據,也必須提供。

代碼示例

	<bean id="accoutService" class="com.gzgs.service.impl.AccoutServiceImpl">
	    <constructor-arg name="name" value="張三"></constructor-arg>
	    <constructor-arg name="age" value="15"></constructor-arg>
	    <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>
    <bean id="now" class="java.util.Date"></bean>

使用set方法注入

涉及的標籤:property
出現的位置:bean標籤的內部
標籤的屬性

name:用於指定注入時所調用的set方法名稱
value:用於提供基本類型和String類型的數據
ref:用於指定其他的bean類型數據。它指的就是在spring的Ioc核心容器中出現過的bean對象

優勢:

創建對象時沒有明確的限制,可以直接使用默認構造函數,有要求在Bean的方法中要有set方法。

弊端:

如果有某個成員必須有值,則獲取對象是有可能set方法沒有執行。

代碼示例

<bean id="now" class="java.util.Date"></bean>
<bean id="accoutService" class="com.gzgs.service.impl.AccoutServiceImpl">
    <property name="name" value="李四"></property>
    <property name="age" value="18"></property>
    <property name="birthday" ref="now"></property>
</bean>

複雜類型的注入/集合類型的注入

用於給List結構集合注入的標籤:

< list> < array> < set>

用於個Map結構集合注入的標籤:

< map> < props>

如果結構相同,標籤可以互換,如list、array、set

代碼示例

 <bean id="accoutService" class="com.gzgs.service.impl.AccoutServiceImpl">
    <property name="myStrs">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </set>
    </property>

    <property name="myList">
        <array>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </array>
    </property>

    <property name="mySet">
        <list>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </list>
    </property>

    <property name="myMap">
        <props>
            <prop key="testC">ccc</prop>
            <prop key="testD">ddd</prop>
        </props>
    </property>

    <property name="myProps">
        <map>
            <entry key="testA" value="aaa"></entry>
            <entry key="testB">
                <value>BBB</value>
            </entry>
        </map>
    </property>
</bean>
本博客純屬個人學習筆記,學習資源來自黑馬訓練營,如有錯誤,感激指正
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章