Spring Framework 基础(02) —— 依赖注入

前言

Spring 容器作为超级大工厂,负责创建、管理所有的 Java 对象,这些对象统称为 Bean。
Spring 容器使用依赖注入(Dependency Injection, DI)的方式,管理容器中 Bean 之间的依赖关系,达成控制反转(Inversion of Control, IoC)的目的。

依赖注入

依赖注入的几种方式

设值注入

原理解析
IoC 容器通过成员变量的 setter 方法注入被依赖对象。
代码示例
想要在 Person 类里注入 Axe 类,从而在 Person 类的方法里,访问到 Axe 类的方法。
类 Person

public class Person {

    private Axe axe;
    /**
     * 设值注入
     */
    public void setAxe(Axe axe) {
   		System.out.println("设值注入 Axe");
        this.axe = axe;
    }
    
    public void useAxe() {
        System.out.println("I want to chop wood");
        // 访问 Axe 类的方法
        System.out.println(axe.chop());
    }

类 Axe

public class Axe {
    public String chop(){
        return "use an axe to chop wood";
    }
}

配置文件 Beans.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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person" class="org.autumn.boot.ssm.study.di.Person">
        <property name="axe" ref="axe"/>
    </bean>
    <bean id="axe" class="org.autumn.boot.ssm.study.di.Axe"/>
</beans>

配置文件中,<bean> 声明 spring bean,id 指定唯一标识,class 指定实现类。
XML 解析器读取配置的内容,由Spring 容器通过反射的方式来创建该实现类,作为 Bean 来使用。
Spring 会检测每个 <bean> 中的 <property> 元素,根据元素内容,调用对应的 setter 方法为 Bean 的成员变量注入值。

通过创建 Spring 容器 ApplicationContext 来获取 beans.xml 中 配置的 Bean 实例。

public class Main {

    public static final String CONFIG_LOCATION = "beans.xml";

    public static void main(String[] args) {
        // 创建 ApplicationContext 容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
        // 从容器中获取 Bean 实例
        Person person = context.getBean(Person.class);
        // 访问 Bean 实例的方法
        person.useAxe();
        // 为 Spring 容器注册关闭钩子
        context.registerShutdownHook();
    }
}

执行结果:

设值注入 Axe
I want to chop wood
use an axe to chop wood

可以看到 Person 类在使用 Axe 类的过程中,不需要自己去创建、维护,直接由 Spring 容器注入。
可以说由依赖注入实现了控制反转,达到了依赖类之间解耦的目的。

构造注入

原理解析
驱动 Spring 在底层以反射的方式执行带参数的构造器,在执行带参数构造器时,可利用构造器参数对成员变量执行初始化。
代码示例
想要在 Person 类里注入 Axe 类,从而在 Person 类的方法里,访问到 Axe 类的方法。
类 Person

public class Person {

    private Axe axe;
    /**
     * 构造注入
     */
    public Person(Axe axe) {
        System.out.println("构造注入 Axe");
        this.axe = axe;
    }
    
    public void useAxe() {
        System.out.println("I want to chop wood");
        // 访问 Axe 类的方法
        System.out.println(axe.chop());
    }

类 Axe

public class Axe {
    public String chop(){
        return "use an axe to chop wood";
    }
}

配置文件 Beans.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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person" class="org.autumn.boot.ssm.study.di.Person">
        <constructor-arg ref="axe"/>
    </bean>
    <bean id="axe" class="org.autumn.boot.ssm.study.di.Axe"/>
</beans>

Spring 根据 <constructor-arg> 元素的定义反射执行相应的构造方法。

如果由多个参数,则可以使用 index=0 来标记,例如:

    <bean id="person" class="org.autumn.boot.ssm.study.di.Person">
        <constructor-arg index="0" value="123"/>
        <constructor-arg index="1" value="hello"/>
    </bean>

通过创建 Spring 容器 ApplicationContext 来获取 beans.xml 中 配置的 Bean 实例。

public class Main {

    public static final String CONFIG_LOCATION = "beans.xml";

    public static void main(String[] args) {
        // 创建 ApplicationContext 容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
        // 从容器中获取 Bean 实例
        Person person = context.getBean(Person.class);
        // 访问 Bean 实例的方法
        person.useAxe();
        // 为 Spring 容器注册关闭钩子
        context.registerShutdownHook();
    }
}

执行结果:

构造注入 Axe
I want to chop wood
use an axe to chop wood

两种注入方法的对比

设值注入和构造注入这两种方法对比而言:

  • 设值注入依赖关系显得更加直观、自然。
  • 对于复杂的依赖关系,构造注入会导致构造器过于笨重。
  • 构造注入更符合高内聚的原则

接口注入

参见下文 : 在 Bean 中获取 Spring 容器
https://blog.csdn.net/u010541670/article/details/113809866

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值