04,spring 构造方法注入和set注入

本文介绍了Spring框架中的依赖注入,包括无参构造方法注入和有参构造方法注入,以及它们的优缺点。在讲解过程中,通过示例展示了如何在XML配置文件中设置构造参数和属性值。当有多个构造方法时,Spring会根据参数个数匹配构造方法,这可能导致问题。因此,文章推荐使用更灵活的Setter注入,它能避免构造方法注入的缺陷,提高代码的可读性和维护性。
摘要由CSDN通过智能技术生成

V哥官网:http://www.vgxit.com

本博客对应视频教程:http://www.vgxit.com/course/23


构造方法注入和set注入


1,概述

我们上节课讲了一下IOC入门,然后我们注入了一个对象到Spring容器,并且通过Spring容器获取到了这个对象。但是,我们思考一下,我们说道了注入就是我们创建一个对象然后把这个对象提交到Spring容器。那么我们思考一下他是如何创建这个对象的呢?


2,无参构造方法注入

所谓无参构造方法注入就是Spring会自动调用我们无参构造方法来创建一个对象,然后再把这个对象提交到Spring容器。像我们上节课讲的入门案例。我们创建Person对象不需要提交任何的参数。


3,有参构造方法注入

对于有一些对象,他有一些属性,这些属性的初始化是通过构造方法传递进去的。这个时候,我们创建对象的时候必须要指定对应的参数。Spring也给我们提供了通过构造器传入参数注入对象的方法。

1,改造一下Person:

package com.vgxit.spring.ktdm.vgioc.beans;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Person {
    private Integer id;
    private String name;
    public void sayHello(String name) {
        System.out.println(this.id + ":" + this.name + " say hello to " + name);
    }
}

2,修改注入配置:

<!--
    bean标签用来定义一个需要Spring创建并且注入到IOC容器的对象
    id表示这个对象的名字
    class表示类型
    -->
    <bean id="person" class="com.vgxit.spring.ktdm.vgioc.beans.Person">
        <!--
        <constructor-arg/>标签就表示对应的构造方法的参数
        index表示参数的位置,从0开始的
        value表示参数的值
        -->
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="V哥"/>
    </bean>

3,测试:

package com.vgxit.spring.ktdm.vgioc.test;

import com.vgxit.spring.ktdm.vgioc.beans.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Ioc001Test {
    public static void main(String[] args) {
        //1,首先通过配置文件获取到Spring的上下文
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-ioc-cfg.xml");
        //2,获取对应的对象,通知Spring的Ioc容器,我需要一个名字叫做Person的bean
        Person person = (Person) ctx.getBean("person");
        //调用方法
        person.sayHello("李一桐");
    }
}


4,有参构造方法注入缺陷

我们上面讲了有参构造方法实现注入。但是我们在实际的开发中,基本上没人使用有参构造方法来实现注入。因为有参构造方法的注入是有非常大的缺陷的。下面我们演示一下这个缺陷。

1,改造Person:

package com.vgxit.spring.ktdm.vgioc.beans;

public class Person {
    private Integer id;
    private String name;
    private String nickName;

    public Person(String name, String nickName) {
        this.name = name;
        this.nickName = nickName;
    }

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public void sayHello(String name) {
        System.out.println(this.id + ":" + this.name + "[" + this.nickName + "]" + " say hello to " + name);
    }
}

这个时候,我们传入如下参数:

<bean id="person" class="com.vgxit.spring.ktdm.vgioc.beans.Person">
        <!--
        <constructor-arg/>标签就表示对应的构造方法的参数
        index表示参数的位置,从0开始的
        value表示参数的值
        -->
        <constructor-arg index="0" value="V哥"/>
        <constructor-arg index="1" value="V哥学IT"/>
    </bean>

这个时候我们可以发现Spring调用了Person的Person(String name, String nickName)方法。但是,如果我们改成下面的参数传入:

<bean id="person" class="com.vgxit.spring.ktdm.vgioc.beans.Person">
        <!--
        <constructor-arg/>标签就表示对应的构造方法的参数
        index表示参数的位置,从0开始的
        value表示参数的值
        -->
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="V哥学IT"/>
    </bean>

这个时候,还是调用的Person(String name, String nickName)。但是我们实际上是想调用Person(Integer id, String name)。但是我们发现Spring永远没有办法帮我们调用到。因为Spring调用有参构造方法的逻辑按照构造方法定义的顺序,从上往下找到第一个满足参数个数匹配的方法来调用。


5,基于Setter的注入

setter注入是Spring中最流行的注入方式,它的原理是先调用无参构造方法来创建对象,然后调用对应的set方法来为属性赋值。用setter的方式可以解决有参构造方法注入的问题。并且可以提高可读性。

1,改造Person:

package com.vgxit.spring.ktdm.vgioc.beans;

import lombok.Setter;

@Setter
public class Person {
    private Integer id;
    private String name;
    private String nickName;

    public void sayHello(String name) {
        System.out.println(this.id + ":" + this.name + "[" + this.nickName + "]" + " say hello to " + name);
    }
}

2,通过property标签来注入对应的属性:

<bean id="person" class="com.vgxit.spring.ktdm.vgioc.beans.Person">
        <property name="id" value="1"/>
        <property name="name" value="V哥"/>
        <property name="nickName" value="V哥学IT"/>
    </bean>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

V哥学It

赏小的一个钱吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值