天天看点

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定义继承

继续阅读