Spring-依赖注入(DI)解释及演示

依赖注入

依赖注入(Dependency Injection,简称DI)是Spring对IOC的一种实现方式。

通过控制反转,对象在被创建的时候,由Spring容器将其所依赖的对象的引用传递给它,也可以理解为,依赖被注入到对象中,所以就被称作为依赖注入。

就是通过Spring,将所有的对象放在一个容器中,再由这个容器将其中被依赖的对象注入到需要该依赖的对象中,听起来确实有点绕,我们看下面的图:
在这里插入图片描述
其中对象的创建和管理,都交由Spring容器来管理,它在创建对象时,会将该对象依赖的对象注入到该对象中。

我们来看看Spring的具体实现方式:
博主的演示环境:

  • idea编辑器
  • Maven项目
1. 先导入Spring相关依赖

建议使用Maven直接导入,这里博主就不再提供各个jar包的下载地址了,需要的可以直接去maven仓库搜索下载,博主这里直接导入依赖即可:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

因为Maven会自动导入该包依赖的其他所有的包,所有博主推荐在使用Spring时直接导入该依赖。
在这里插入图片描述

2. 准备Spring的配置文件

我们在resources目录下创建一个beans.xml的配置文件,名字可以任意取,Spring官方建议使用applicationContext.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">



</beans>

我们简单了解一下该配置文件中的一些相关配置(这里仅仅介绍beans约束下的一些配置):

  • bean:配置一个bean对象,交由Spring接管
    • id:bean的唯一标识符,可以理解为我们new变量时的变量名
    • class:bean对象所对应的全限定类名
    • name:也是别名 而且该属性还能取多个别名
    • scope:作用域(这里了解singleton单例和prototype原型即可)
    • autowire:自动注入方式(byName和byType)
  • alias:别名,就是为一个bean对象可以取多个别名
    • name:指定bean的唯一标识符id
    • alias:别名
  • import:用于将多个xml文件导入一个xml文件中,多用于协同开发
    • resource:指定导入的资源
3. 准备三个Java实体类

Address:

package com.ara.pojo;

public class Address {
    private String name;
    
    public Address(String name) {
	this.name = name;	
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Address{" +
                "name='" + name + '\'' +
                '}';
    }
}

Student:

package com.ara.pojo;

import java.util.*;

public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Map<String,String> card;
    private Set<String> games;
    private Properties info;
    private String wife;

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbies=" + hobbies +
                ", card=" + card +
                ", games=" + games +
                ", info=" + info +
                ", wife='" + wife + '\'' +
                '}';
    }
}

User:

package com.ara.pojo;

public class User {

    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

博主在Address中提供了带参构造和对应属性的set方法,在Student类中准备了各种各样的属性值,并提供了对应属性的set方法,在User类中也准备了无参构造和带参构造,以及对应属性的set方法,便于下面演示注入。

4. 配置bean到Spring容器中

这里只需要在第二步创建的配置文件中添加即可

4.1 构造器注入

这里我们以Address为演示(这里博主为该类值提供了一个构造方法,所以创建bean时,必须为它的构造方法赋值,Spring会根据配置的bean去找对应的构造方法):

  • 按构造方法中参数下标注入
<bean id="address1" class="com.ara.pojo.Address">
    <!--为构造方法中下标为0的参数赋值为China-->
    <constructor-arg index="0" value="China"/>
</bean>
  • 按构造方法中参数类型注入(不建议使用,如果几个参数类型一致,后果。。。)
<bean id="address2" class="com.ara.pojo.Address">
    <!--为构造方法中类型为java.lang.String的参数赋值为四川-->
    <constructor-arg type="java.lang.String" value="四川"/>
</bean>
  • 按构造方法重参数名字注入
<bean id="address3" class="com.ara.pojo.Address">
    <!--为构造方法中名为name的参数赋值为成都-->
    <constructor-arg name="name" value="成都"/>
</bean>
4.2 set注入

这里以Student为例(注意一定要存在对应属性的set方法哦):

<bean id="student" class="com.ara.pojo.Student">
    <!--  1.普通简单值注入  -->
    <property name="name" value="Ara_Hu"/>

    <!--  2.bean引用注入 ref  -->
    <property name="address" ref="address1"/>

    <!--  3.数组注入 内嵌array标签  -->
    <property name="books">
        <array>
            <value>西游记</value>
            <value>红楼梦</value>
            <value>水浒传</value>
            <value>三国演义</value>
        </array>
    </property>

    <!--  4.list注入  -->
    <property name="hobbies">
        <list>
            <value>听歌</value>
            <value>打代码</value>
            <value>抽烟</value>
            <value>喝酒</value>
        </list>
    </property>

    <!--  5.map注入  -->
    <property name="card">
        <map>
            <entry key="身份证" value="000000000000" />
            <entry key="银行卡" value="111111111111" />
        </map>
    </property>

    <!--  6.set注入  -->
    <property name="games">
        <set>
            <value>LOL</value>
            <value>CF</value>
            <value>QQ</value>
            <value>CS</value>
        </set>
    </property>

    <!--  7.properties注入  -->
    <property name="info">
        <props>
            <prop key="学号">20111111</prop>
            <prop key="年级">2011</prop>
            <prop key="专业">计算机</prop>
        </props>
    </property>

    <!--  8.null注入  -->
    <property name="wife">
        <null/>
    </property>

</bean>
4.3 扩展注入方式

p命名空间和c命名空间 这里需要注意需要在配置文件中导入头约束:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    
    
</beans>

这里就以User类为例

  • P命名空间
<!--  p命名空间就相当于<property>标签的简化版  -->
<bean id="user1" class="com.ara.pojo.User" p:name="Ara_Hu" p:age="18"/>
  • C命名空间
<!--  c命名空间就相当于<constructor-arg>标签的简化版  -->
<bean id="user2" class="com.ara.pojo.User" c:name="Ara_Hu" c:age="20"/>

在这几个例子中,博主将几乎所有的注入类型都演示了,接下来我们测试一下

5. 测试代码
@Test
public void springTest01(){

    //读取配置文件 获取Spring上下文对象 可以理解为Spring的容器对象
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    //获取学生对象
    Student student = context.getBean("student",Student.class);
    System.out.println(student);

    //获取User对象
    User user = context.getBean("user1", User.class);
    System.out.println(user);

}

测试结果:
在这里插入图片描述
说明注入成功了。

通过上述演示,我们从头至尾都没有手动的new过对象,而是从Spring的上下文对象中获取出的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值