依赖注入(Dependency
Injection,简称DI)与控制反转(IoC)的含义相同,只不过这两个称呼是从两个角度描述同一个概念。下面通过简单地语言来进行描述

概念

  • 通常情况下,调用者会采用"new被调用者"的代码方式来创建对象,如下图。但这种方式会导致调用者与被调用者之间的耦合性增加,不利于后期项目的升级和维护。
  • 而使用了Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系。这样控制权便由应用代码转移到Spring容器,控制权发生了反转,这就是Spring的控制反转
  • 从Spring容器来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这就相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入

spring 依赖注入和new 关键字 spring依赖注入的概念_依赖注入

实现方式

能注入的数据:有三类

  1. 基本类型和String
  2. 其他bean类型(在配置文件中或者注解配置过的bean)
  3. 复杂类型/集合类型

注入的方式:有三种

  1. 使用构造函数提供
  2. 使用set方法提供
  3. 第三种:使用注解提供

构造函数注入:
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
name:用于指定给构造函数中指定名称的参数赋值 常用的
=以上三个用于指定给构造函数中哪个参数赋值===================
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

优势:
        在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    弊端:
        改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

步骤:

  1. 创建一个Maven Project,并在pom.xml中配置spring框架
<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>day01_eesy_04Spring</groupId>
<artifactId>day01_spring04</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
</dependencies>
  1. 在com.itheima.service包中创建接口IUserService接口,在接口中编写say()方法
public interface IUserService {
void say();
}
  1. 在com.itheima.service.Impl包中创建IUserService接口的实现类UserServiceImpl,在类中声明name、id、birthday属性,并添加对应方法
public class UserServiceImpl implements IUserService {
private Integer id;
private String username;
private Date birthday;

public UserServiceImpl(Integer id, String username, Date birthday) {
    this.id = id;
    this.username = username;
    this.birthday = birthday;
}


public void say() {
    System.out.println("id="+id+",username="+username+",birthday="+birthday);
}
}
  1. 在resource中编写配置文件bean.xml,创建id为userservice的Bean,该Bean用于实例化UserServiceImpl类的信息,注意的是,当要输出类型为date时要创建一个新的bean在通过ref获取
<?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="com.itheima.service.Impl.UserServiceImpl">
        <constructor-arg name="username" value="张三"></constructor-arg>
        <constructor-arg name="id" value="36"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>
    <bean id="now" class="java.util.Date"></bean>
    </bean>
  1. 在com.itheima.ui中创建Client,来对程序进行测试
public class Client {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        UserServiceImpl userService = (UserServiceImpl) applicationContext.getBean("userservice");	      
        userService.say();
    }
}

控制台输出结果如下

spring 依赖注入和new 关键字 spring依赖注入的概念_spring 依赖注入和new 关键字_02

set方法注入 更常用的方式

  • 涉及的标签:property
  • 出现的位置:bean标签的内部
  • 标签的属性
  1. name:用于指定注入时所调用的set方法名称
  2. value:用于提供基本类型和String类型的数据
  3. ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    优势:创建对象时没有明确的限制,可以直接使用默认构造函数
    弊端:如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
<!-- 复杂类型的注入/集合类型的注入
用于给List结构集合注入的标签:
    list array set
用于个Map结构集合注入的标签:
    map  props
结构相同,标签可以互换
 -->

步骤:

  1. 在上一个的基础上在com.itheima.service.Impl包中创建IUserService接口的实现类UserServiceImpl3,在类中声明name、id、birthday属性,并添加对应方法
public class UserServiceImpl3 implements IUserService {
	 	private List<String> list;
	    private String[] strings;
	    private Map<String,String> map;
	    private Properties properties;
	    private Set<String> set;
	
	    public void setList(List<String> list) {
	        this.list = list;
	    }
	
	    public void setStrings(String[] strings) {
	        this.strings = strings;
	    }
	
	    public void setMap(Map<String, String> map) {
	        this.map = map;
	    }
	
	    public void setProperties(Properties properties) {
	        this.properties = properties;
	    }
	
	    public void setSet(Set<String> set) {
	        this.set = set;
	    }
	
	    public void say() {
	        System.out.println(Arrays.toString(strings));
	        System.out.println(list);
	        System.out.println(set);
	        System.out.println(map);
	        System.out.println(properties);
	    }
	}
  1. 在bean.xml中再创建一个id为userservice02的Bean,该Bean用于实例化UserServiceImpl类中的信息
<bean id="userservice02" class="com.itheima.service.Impl.UserServiceImpl3">
            <property name="strings">
                <set>
                    <value>AAA</value>
                    <value>BBB</value>
                    <value>CCC</value>
                </set>
            </property>
            <property name="list">
                <array>
                    <value>listA</value>
                    <value>listB</value>
                    <value>listC</value>
                </array>
            </property>
            <property name="set">
                <set>
                    <value>AAA</value>
                    <value>BBB</value>
                    <value>CCC</value>
                </set>
            </property>
            <property name="map">
                <props>
                    <prop key="Test1">hehe</prop>
                    <prop key="Test2">haha</prop>
                </props>
            </property>
            <property name="properties">
                <props>
                    <prop key="protertie1">ppp1</prop>
                    <prop key="protertie2">ppp2</prop>
                </props>
            </property>
        </bean>
  1. 在com.itheima.ui中创建Client02,来对程序进行测试
public class Client {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        UserServiceImpl3 userService = (UserServiceImpl3) applicationContext.getBean("userservice02");
        userService.say();
    }
}

在控制台的输出结果如下

spring 依赖注入和new 关键字 spring依赖注入的概念_数据_03