天天看點

Spring IoC之DISpring IoC之DI(依賴注入)

Spring IoC之DI(依賴注入)

一、闡述

DI: Dependency(依賴) Injection(注入)

官方解釋

Spring IoC之DISpring IoC之DI(依賴注入)

個人了解:

依賴:Bean依賴Spring IoC容器來控制類的建立和時間,以及Bean的生命周期由IoC容器管理,降低類與類之間的依賴,轉而依賴IoC容器

注入:将所需的類、屬性、各種資源…注入到目标類中

好處:Bean之間的依賴交給Ioc容器,降低Bean間的耦合。不用在依賴類中new對象,當被依賴類發生變化時隻需要更改Bean的配置資訊即可

二、DI注入方式

1、基于構造函數的依賴注入

A類構造方法中的構造參數依賴B類

SimpleMovieLister.java
package com.hgl.day02;

public class SimpleMovieLister {
    private MovieFinder movieFinder;
    private MovieDownloader movieDownloader;
    public SimpleMovieLister(MovieFinder movieFinder, MovieDownloader movieDownloader){
        System.out.println("Injection movieFinder、movieDownloader");
        this.movieFinder = movieFinder;
        this.movieDownloader = movieDownloader;
    }
    public void startWork(){
        movieFinder.starFinder();
        movieDownloader.startWork();
    }
}

           
MovieFinder.java
package com.hgl.day02;

public class MovieFinder {
    public MovieFinder(){
        System.out.println("movieFinder's constructor");
    }
    public void starFinder(){
        System.out.println("movieFinder has started");
    }
}

           
MovieDownloader.java
package com.hgl.day02;

public class MovieDownloader {
    public MovieDownloader(){
        System.out.println("movieDownload's constructor");
    }
    public void startWork(){
        System.out.println("movieDownloader has started");
    }
}

           
xml配置
<bean id="simpleMovieLister" class="com.hgl.day02.SimpleMovieLister">
        <constructor-arg ref="movieFinder"/>
        <constructor-arg ref="movieDownload"/>
    </bean>
    <bean id="movieFinder" class="com.hgl.day02.MovieFinder"/>
    <bean id="movieDownload" class="com.hgl.day02.MovieDownloader"/>

           
  1. 當構造參數有多個對象時,xml配置檔案中當

    constructor-arg

    标簽要按照構造參數當順序進行注入
  2. 當注入當為基本資料類型時,可以通過以下方式差別對應的構造參數

使用type屬性對參數對類型進行區分

<constructor-arg type="int" value="2001"/>
<constructor-arg type="java.lang.String" value="Zara"/>
           

使用index索引對應參數對索引,索引從0開始

<constructor-arg index="0" value="7500000"/>
 <constructor-arg index="1" value="42"/>
           

使用name對應參數的名字

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>
           

參照Spring5.2.7官方文檔https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-constructor-injection

2、基于setter的依賴注入

通過設定私有屬性,setter方法和getter方法來設值和擷取屬性

SetterMovieLister.java
package com.hgl.day02;

public class SetterMovieLister {
    private MovieFinder movieFinder;
    private MovieDownloader movieDownloader;
    private String message;

    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    public void setMovieDownloader(MovieDownloader movieDownloader) {
        this.movieDownloader = movieDownloader;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public MovieFinder getMovieFinder() {
        return movieFinder;
    }

    public MovieDownloader getMovieDownloader() {
        return movieDownloader;
    }

    public void getMessage() {
        System.out.println("message : " + message);
        movieFinder.starFinder();
        movieDownloader.startWork();
    }
}

           

MovieFinder.java和MovieDownloader.java為構造注入使用的例子

<bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister">
        <property name="movieFinder" ref="movieFinder"/>
        <property name="movieDownloader" ref="movieDownload"/>
        <property name="message" value="Setter Injection"/>
</bean>

           

xml配置可使用p 命名空間進行簡化xml的内容,可改寫成

但是要在beans根目錄下,添加命名空間

xmlns:p="http://www.springframework.org/schema/

p"

<bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister" 
    p:movieFinder="movieFinder" 
    p:movieDownloader="movieDownloder"
    p:message="Setter Injection"
/>

           

官網的另一種方式使用工具包中的Propreties(java.util.Properties)

<bean id="mappings"
    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">

    <!-- typed as a java.util.Properties -->
    <property name="properties">
        <value>
            jdbc.driver.className=com.mysql.jdbc.Driver
            jdbc.url=jdbc:mysql://localhost:3306/mydb
        </value>
    </property>
</bean>

           

三、内部Bean(Inner Bean)

<bean id="movieFinder" class="com.hgl.day02.MovieFinder"/>
<bean id="movieDownload" class="com.hgl.day02.MovieDownloader"/>
<bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister">
        <property name="movieFinder" ref="movieFinder"/>
        <property name="movieDownloader" ref="movieDownload"/>
        <property name="message" value="Setter Injection"/>
</bean>

           

以上bean配置可改寫成:

<bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister">
        <property name="movieFinder">
            <bean id="movieFinder" class="com.hgl.day02.MovieFinder"/>
        </property>
        <property name="movieDownloader">
            <bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister">
        </property>
        
</bean>

           

idref – 該元素隻是将容器中另一個 bean 的(字元串值 - 而不是引用)傳遞給 或 元素的一種防錯方法。

<bean id="movieFinder" class="com.hgl.day02.MovieFinder"/>
<bean id="movieDownload" class="com.hgl.day02.MovieDownloader"/>
<bean id="setterMovieLister" class="com.hgl.day02.SetterMovieLister">
        <property name="movieFinder">
            <idref bean="movieFinder">
        </property>
        <property name="movieDownloader">
            <idref bean="movieDownload">
        </property>
        
</bean>

           

四、Spring注入集合

Spring IoC之DISpring IoC之DI(依賴注入)

List、Set、Map、Properties

InjectionCollection.java
package com.hgl.day02;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class InjectionCollection {
    Properties addressProps;
    List addressList;
    Map addressMap;
    Set addressSet;

    public void setAddressProps(Properties addressProps) {
        this.addressProps = addressProps;
    }

    public void setAddressList(List addressList) {
        this.addressList = addressList;
    }

    public void setAddressMap(Map addressMap) {
        this.addressMap = addressMap;
    }

    public void setAddressSet(Set addressSet) {
        this.addressSet = addressSet;
    }

    public Properties getAddressProps() {
        System.out.println("Property Elements :"  + addressProps);
        return addressProps;
    }

    public List getAddressList() {
        System.out.println("List Elements :"  + addressList);
        return addressList;
    }

    public Map getAddressMap() {
        System.out.println("Map Elements :"  + addressMap);
        return addressMap;
    }

    public Set getAddressSet() {
        System.out.println("Set Elements :"  + addressSet);
       return addressSet;
    }
}


           
package com.hgl.day02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;



public class CollectionInjectionMainApp {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("BeansConfigDay02.xml");
        InjectionCollection collection = (InjectionCollection) context.getBean("injectionCollection");
        collection.getAddressProps();
        collection.getAddressList();
        collection.getAddressMap();
        collection.getAddressSet();


    }
}


           
<bean id="address1" class="com.hgl.day02.Address1"/>
    <bean id="address2" class="com.hgl.day02.Address2"/>
    <bean id="injectionCollection" class="com.hgl.day02.InjectionCollection">
        <property name="addressProps">
           <props>
               <prop key="address0">廣州</prop>
               <prop key="address1">深圳</prop>
               <prop key="address2">韶關</prop>
           </props>
        </property>
        <property name="addressList">
            <list>
                <value>廣州</value>
                <ref bean="address1"/>
                <ref bean="address2"/>
            </list>
        </property>
        <property name="addressMap">
            <map>
                <entry key="address0" value="廣州"/>
                <entry key="address1" value-ref="address1"/>
                <entry key="address2" value-ref="address2"/>
            </map>
        </property>
        <property name="addressSet">
            <set>
                <value>廣州</value>
                <ref bean="address1"/>
                <ref bean="address2"/>
            </set>
        </property>
    </bean>

           

ps:集合之間也可以Spring定義繼承

繼續閱讀