Spring5(2)- 注入

1 bean 對象的三種創建方式

1.1 通過構造函數創建bean對象

在默認情況下,當在spring配置文件中寫了一個bean標籤,並提供了 class 屬性,spring就會調用默認的構造函數創建對象。如果沒有默認構造函數,則對象創建失敗。


1.2 通過靜態工廠創建對象

package com.tzb.factory;

import com.tzb.service.IAccountService;
import com.tzb.service.impl.AccountServiceImpl;

/**
 * 模擬一個靜態工廠
 */
public class StaticBeanFactory {
    public static IAccountService getBean(){
        return new AccountServiceImpl();
    }
}

  • bean.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--導入 spring 約束-->
<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 definitions here -->

    <!--配置業務層對象-->
    <!--
        bean標籤,讓spring讀取配置後創建對象
        id:對象的唯一標識
    -->
    <bean id="accountService" class="com.tzb.service.impl.AccountServiceImpl">

    </bean>

    <!--配置持久層對象-->
    <bean id="accountDao" class="com.tzb.dao.impl.IAccountDaoImpl"></bean>

    <!--靜態工廠創建
        factory-method: 指定創建 bean 對象的方法,可以是靜態,也可以不是
    -->
    <bean id="staticAccountService" class="com.tzb.factory.StaticBeanFactory" factory-method="getBean"></bean>

</beans>

1.3 通過實例工廠創建 bean 對象

package com.tzb.factory;

import com.tzb.service.IAccountService;
import com.tzb.service.impl.AccountServiceImpl;

/**
 * 模擬一個靜態工廠
 */
public class InstanceBeanFactory {
    public  IAccountService getBean(){
        return new AccountServiceImpl();
    }
}

  • bean.xml
 <!--實例工廠創建-->
    <bean id="instanceFactory" class="com.tzb.factory.InstanceBeanFactory"></bean>
    <bean id="instanceAccountService" factory-bean="instanceFactory" factory-method="getBean"></bean>

2 bean 對象的作用範圍

2.1 可以通過配置的方式指定

  • 配置的屬性: bean 標籤的 scope 屬性
  • singleton: 默認,單例的,【最常用】
  • prototype : 多例,每次創建新的實例
  • request : 一個對象在當前請求和請求轉發中可用
  • session: 會話範圍
  • global-session : 全局會話

3 bean 對象的生命週期

3.1 單例對象

  • 出生:容器創建對象出生
  • 活着:只要容器存在,對象就一直可用
  • 死亡:容器銷燬

3.2 多例對象

  • 出生:每次使用時,容器會創建對象
  • 活着:只要對象在使用,就一直活着
  • 死亡:垃圾回收器回收

4 spring依賴注入

4.1 注入方式(3種)

  1. 通過構造函數注入
  2. 通過 set 方法注入

 構造函數注入
package com.tzb.service.impl;

import com.tzb.service.IAccountService;

import java.util.Date;

public class AccountServiceImpl implements IAccountService {

    private String name;
    private Integer age;
    private Date birthday;

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

    @Override
    public void save() {
        System.out.println("調用持久層的執行方法:" + name + "," + age + "," + birthday);
    }
}

  • bean.xml
 <!--使用構造函數注入
        涉及的標籤:constructor-arg,bean 標籤內部的子標籤
        標籤的屬性:
            type:指定要注入的參數類型(在構造函數中)
            index:指定要注入的參數在構造函數索引的位置
            name:指定參數在構造函數中的名稱
            value:指定注入的數據內容,只能指定基本數據類型和String
            ref : 指定其他 bean類型數據,寫的是其他bean (存在於spring容器中)的id
    -->
    <bean id="nowDate" class="java.util.Date"></bean>
    <bean id="accountService" class="com.tzb.service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="麥克"></constructor-arg>
        <constructor-arg name="age" value="20"></constructor-arg>
        <constructor-arg name="birthday" ref="nowDate"></constructor-arg>
    </bean>

  • 測試
public class Client {

    /**
     * 獲取 spring 的核心容器,並且根據bean的id獲取對象
     * @param args
     */
    public static void main(String[] args) {
        // 獲取核心容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

        // 根據 bean id 獲取對象
        IAccountService accountService = (IAccountService) ac.getBean("accountService");

        accountService.save();

    }
}

在這裏插入圖片描述


 使用 set 方法注入【常用】
public class AccountServiceImpl implements IAccountService {

    private String name;
    private Integer age;
    private Date birthday;

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

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

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

    @Override
    public void save() {
        System.out.println("調用持久層的執行方法:" + name + "," + age + "," + birthday);
    }
}

<!-- set 方法注入
        涉及的標籤:property,該標籤也是要寫在 bean 標籤內部的子標籤
        標籤的屬性:
            name:指定的是set方法的名稱,set後面的部分
            value:指定注入的數據內容,只能指定基本數據類型和String
            ref : 指定其他 bean類型數據,寫的是其他bean (存在於spring容器中)的id
    -->
    <bean id="nowDate" class="java.util.Date"></bean>
    <bean id="accountService" class="com.tzb.service.impl.AccountServiceImpl">
         <property name="name" value="Mike"></property>
         <property name="age" value="25"></property>
         <property name="birthday" ref="nowDate"></property>
    </bean>

使用 p 名稱空間注入
本質仍然是需要 set 方法,同時在配置文件導入 p 名稱空間

在這裏插入圖片描述

<bean id="nowDate" class="java.util.Date"></bean>
    <bean id="accountService"
          class="com.tzb.service.impl.AccountServiceImpl"
          p:name="Mike"
          p:age="26"
          p:birthday-ref="nowDate">

    </bean>

4.2 注入內容

  1. 基本數據類型和 String
  2. 其他 bean 類型
  3. 複雜類型(集合類)

集合類型注入
public class AccountServiceImpl implements IAccountService {

    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 setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

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

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

    @Override
    public void save() {

        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);

        System.out.println(myMap);
        System.out.println(mySet);
        System.out.println(myProps);
    }
}
  • bean.xml
    結構相同,標籤可以互換
 <!--複雜數據類型注入-->
    <bean id="accountService" class="com.tzb.service.impl.AccountServiceImpl">
        <!--數組注入-->
        <property name="myStrs">
            <array>
                <value>AAA</value>
                <value>BBB</value>
            </array>
        </property>

        <!--List-->
        <property name="myList">
            <list>
                <value>AAA</value>
                <value>BBB</value>
            </list>
        </property>

        <!--Set-->
        <property name="mySet">
            <set>
                <value>AAA</value>
                <value>BBB</value>
            </set>
        </property>

        <!--map注入-->
        <property name="myMap">
            <map>
                <entry key="A" value="111"></entry>
                <entry key="B">
                    <value>222</value>
                </entry>
            </map>
        </property>

        <!--properties注入-->
        <property name="myProps">
            <props>
                <prop key="PA">111</prop>
                <prop key="PB">222</prop>
            </props>
        </property>
    </bean>

5 Eclipse 斷網下添加 spring 標籤提示

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