1. 程式人生 > >Spring學習筆記(一)

Spring學習筆記(一)

搭建Spring的環境

第一步:
引入Spring的座標

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

建立配置檔案:bean.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--建立物件--> <bean id="userService"
class="money.com.service.Impl.IUServicesImpl">
</bean> <bean id="userDao" class="money.com.dao.Impl.IUserDaoImpl"></bean> </beans>

讀取配置檔案獲取物件:

/**
     * 第一次測試Spring
     */
    @Test
    public void testGetSpring() {
        //載入配置檔案
        ApplicationContext app = new
ClassPathXmlApplicationContext("bean.xml"); IUserService userService = (IUserService) app.getBean("userService"); IUserDao userDao = app.getBean("userDao", IUserDao.class); System.out.println(userDao); System.out.println(userService); }

這裡的ApplicationContext是一個介面需要介面的實現類
分析ApplciationContext的三種實現類

獲取spring的Ioc核心容器,並根據id獲取物件
     *
     * ApplicationContext的三個常用實現類:
     *      ClassPathXmlApplicationContext:它可以載入類路徑下的配置檔案,要求配置檔案必須在類路徑下。不在的話,載入不了。(更常用)
     *      FileSystemXmlApplicationContext:它可以載入磁碟任意路徑下的配置檔案(必須有訪問許可權)
     *
     *      AnnotationConfigApplicationContext:它是用於讀取註解建立容器的,是明天的內容。
     *
     * 核心容器的兩個介面引發出的問題:
     *  ApplicationContext:     單例物件適用              採用此介面
     *      它在構建核心容器時,建立物件採取的策略是採用立即載入的方式。也就是說,只要一讀取完配置檔案馬上就建立配置檔案中配置的物件。
     *
     *  BeanFactory:            多例物件使用
     *      它在構建核心容器時,建立物件採取的策略是採用延遲載入的方式。也就是說,什麼時候根據id獲取物件了,什麼時候才真正的建立物件。

建立Bean的三種方式:
第一種:

 <!--建立Bean的三種方式 -->
    <!-- 第一種方式:使用預設建構函式建立。
            在spring的配置檔案中使用bean標籤,配以id和class屬性之後,且沒有其他屬性和標籤時。
            採用的就是預設建構函式建立bean物件,此時如果類中沒有預設建構函式,則物件無法建立。

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

對應下面的程式碼
這裡必須是預設的建構函式建立物件

  public IUServicesImpl(){
        System.out.println("物件建立了......");
    }

第二種:

<!-- 第二種方式: 使用普通工廠中的方法建立物件(使用某個類中的方法建立物件,並存入spring容器)
    <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
    -->

對應的java程式碼

public class BeanFactory {
    public IUserService getUserService(){
        return new IUServicesImpl();
    }
}

第三種:

<!-- 第三種方式:使用工廠中的靜態方法建立物件(使用某個類中的靜態方法建立物件,並存入spring容器)
    <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>
    -->

對應的java程式碼:

public class StaticFactory {
    public static IUserService getUserService(){
        return new IUServicesImpl();
    }
}

來學習bean的作用範圍:
bean利用建構函式建立的預設是單例模式

bean的作用範圍調整
        bean標籤的scope屬性:
            作用:用於指定bean的作用範圍
            取值: 常用的就是單例的和多例的
                singleton:單例的(預設值)
                prototype:多例的
                request:作用於web應用的請求範圍
                session:作用於web應用的會話範圍
                global-session:作用於叢集環境的會話範圍(全域性會話範圍),當不是叢集環境時,它就是session

bean的生命週期:

bean物件的生命週期
            單例物件
                出生:當容器建立時物件出生
                活著:只要容器還在,物件一直活著
                
                死亡:容器銷燬,物件消亡 
                //父類的裡面的方法close()
                總結:單例物件的生命週期和容器相同
            多例物件
                出生:當我們使用物件時spring框架為我們建立
                活著:物件只要是在使用過程中就一直活著。
                死亡:當物件長時間不用,且沒有別的物件引用時,由Java的垃圾回收器回收

Spring的依賴注入:

spring中的依賴注入
        依賴注入:
            Dependency Injection
        IOC的作用:
            降低程式間的耦合(依賴關係)
        依賴關係的管理:
            以後都交給spring來維護
        在當前類需要用到其他類的物件,由spring為我們提供,我們只需要在配置檔案中說明
        依賴關係的維護:
            就稱之為依賴注入。
         依賴注入:
            能注入的資料:有三類
                基本型別和String
                其他bean型別(在配置檔案中或者註解配置過的bean)
                複雜型別/集合型別
             注入的方式:有三種
                第一種:使用建構函式提供
                第二種:使用set方法提供
                第三種:使用註解提供

第一種通過建構函式注入:

建構函式注入:
        使用的標籤:constructor-arg
        標籤出現的位置:bean標籤的內部
        標籤中的屬性
            type:用於指定要注入的資料的資料型別,該資料型別也是建構函式中某個或某些引數的型別
            index:用於指定要注入的資料給建構函式中指定索引位置的引數賦值。索引的位置是從0開始
            name:用於指定給建構函式中指定名稱的引數賦值                                        常用的
            =============以上三個用於指定給建構函式中哪個引數賦值===============================
            value:用於提供基本型別和String型別的資料
            ref:用於指定其他的bean型別資料。它指的就是在spring的Ioc核心容器中出現過的bean物件

        優勢:
            在獲取bean物件時,注入資料是必須的操作,否則物件無法建立成功。
        弊端:
            改變了bean物件的例項化方式,使我們在建立物件時,如果用不到這些資料,也必須提供
<!--建立物件-->
<bean id="userService" class="money.com.service.Impl.IUServicesImpl">
    <constructor-arg name="name" value="泰斯特"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
    <!-- 配置一個日期物件 -->
    <bean id="now" class="java.util.Date"></bean>

對應的java程式碼:

 //如果是經常變化的資料,並不適用於注入的方式
    private String name;
    private Integer age;
    private Date birthday;

    public IUServicesImpl(String name,Integer age,Date birthday){
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

set方法注入:

set方法注入                更常用的方式
        涉及的標籤:property
        出現的位置:bean標籤的內部
        標籤的屬性
            name:用於指定注入時所呼叫的set方法名稱
            value:用於提供基本型別和String型別的資料
            ref:用於指定其他的bean型別資料。它指的就是在spring的Ioc核心容器中出現過的bean物件
        優勢:
            建立物件時沒有明確的限制,可以直接使用預設建構函式
        弊端:
            如果有某個成員必須有值,則獲取物件是有可能set方法沒有執行
 <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
        <property name="name" value="TEST" ></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>            

這裡根據的實set方法注入和變數名沒有關係

 //如果是經常變化的資料,並不適用於注入的方式
    private String name;
    private Integer age;
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

注入集合:

複雜型別的注入/集合型別的注入
        用於給List結構集合注入的標籤:
            list array set
        用於個Map結構集合注入的標籤:
            map  props
        結構相同,標籤可以互換
<bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3">
        <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>

對應的java程式碼:

 private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }