三、Spring中的依赖注入与自动装配

  • 依赖注入DI (Dependency Injection):从应用程序的角度描述,创建对象实例时,为这个对象注入属性值或其它对象实例,(依赖于容器注入它所需要的外部资源)。实现

  • 控制反转从容器的角度描述,创建对象实例的控制权从应用程序,反转到IOC容器控制(在xml文件控制),强调容器的作用。负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入了它依赖的实例,因此控制翻转也可以称之为依赖注入。概念

    依赖注入的两种方式

    • 构造器注入(构造方法)
    • set方法注入

1 构造方法注入

1.1 基本数据类型

简单数据类型字符串。

1.为实体类添加构造方法

public class User {
    private String name;
    private String sex;
    private int age;

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

2. 修改配置文件

  • constructor-arg标签属性
    • name属性:通过参数名找到参数列表中对应参数
    • index属性:通过参数在参数列表中的索引找到参数列表中对应参数,index从0开始。
    • type属性:通过参数数据类型找到参数列表中对应参数
    • value属性:设置参数列表参数对应的值,用于设定基本数据类型和String类型的数据
    • ref属性:如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值
  • constructor-arg子标签:
    • ref子标签:对应ref属性,该标签name属性的属性值为另一个bean标签id或name属性的属性
    • value子标签:对应value属性,用于设置基本数据类型或String类型的参数值;
    • list子标签:为数组或List类型的参数赋值
    • set子标签:为Set集合类型参数赋值
    • map子标签:为Map集合类型参数赋值
    • props子标签:为Properties类型的参数赋值
<bean id = "user" class="com.qlit.bean.User">
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="sex" value=""/>
    <constructor-arg name="age" value="22"/>
</bean>

1.2 拓展Lombok

使用lombok,快速生成常用方法提高开发速度。

  1. idea安装插件

    文件➡️设置➡️插件,搜索Lombok

  2. 引入依赖

​ 中央仓库地址:https://mvnrepository.com/

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
    <scope>provided</scope>
</dependency>
  1. 修改实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private String sex;
    private Integer age;

    public void sayHello(){
        System.out.println("hello");
    }

}
  1. 其他说明

@Getter/@Setter: 作用类上,生成所有成员变量的getter/setter方法;
作用于成员变量上,生成该成员变量的getter/setter方法。

@ToString: 作用于类,覆盖默认的toString()方法

@EqualsAndHashCode: 作用于类,覆盖默认的equals和hashCode

@NoArgsConstructor生成无参构造器;

@RequiredArgsConstructor生成包含final和@NonNull注解的成员变量的构造器;

@AllArgsConstructor生成全参构造器

@Data: 作用于类上,注解集合,使用它相当于使用下列注解:

  • @ToString
  • @EqualsAndHashCode
  • @Getter
  • @Setter
  • @RequiredArgsConstructor

@Builder: 作用于类上,将类转变为建造者模式

@Log: 作用于类上,生成日志变量

1.3 自定义类型

  1. 定义idcard类,生成构造方法等。
  2. 实体类user中添加private IdCard idcard属性,并更新构造方法。
public class IdCard {
    int id;
    String code;
   }

xml方式一

<bean id="idcard" class="com.yiwu.pojo.IdCard">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="code" value="2222222"/>
</bean>

 <bean id = "user3" class="com.yiwu.pojo.User">
     <constructor-arg name="name" value="张三"/>
     <constructor-arg name="sex" value=""/>
     <constructor-arg name="age" value="22"/>
     <constructor-arg name="idcard" ref="idcard"/>
 </bean>

xml方式二

 <bean id = "user4" class="com.yiwu.pojo.User">
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="sex" value=""/>
        <constructor-arg name="age" value="22"/>
        <constructor-arg name="idcard">
            <bean class="com.yiwu.pojo.IdCard">
                <constructor-arg name="id" value="1"/>
                <constructor-arg name="code" value="2222222"/>
            </bean>
        </constructor-arg>
    </bean>

1.4 日期类型date

实体类中添加private Date brithday属性,并更新构造方法。

方式一

对于dete对象同样利用其构造方法。

在这里插入图片描述

<bean id="b" class="java.util.Date">
    <constructor-arg name="year" value="10"/>
    <constructor-arg name="month" value="11"/>
    <constructor-arg name="date" value="2"/>    
</bean>

<bean id = "user5" class="com.yiwu.pojo.User">
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="sex" value=""/>
    <constructor-arg name="age" value="22"/>
    <constructor-arg name="brithday" ref="b"/>
</bean>

方式二

 <bean id = "user6" class="com.yiwu.pojo.User">
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="sex" value=""/>
        <constructor-arg name="age" value="22"/>
        <constructor-arg name="brithday">
            <bean class="java.util.Date">
                <constructor-arg name="year" value="10"/>
                <constructor-arg name="month" value="10"/>
                <constructor-arg name="date" value="2"/>
            </bean>
        </constructor-arg>
    </bean>

1.5 集合类型

🔴List类型

  1. 实体类添加private List < String> product;属性,生成对应构造方法(此处仅仅生成了product的构造方法)

  2. 如果List集合元素为基本数据类型包装类或String类型,则可通过value标签设置值;如果为其它引用类型的数据则可以通过bean标签或ref标签设置元素值,每对标签设置一个集合元素。

 <bean id = "user7" class="com.yiwu.pojo.User">
       <constructor-arg name="product">
           <list>
               <value>aaa</value>
               <value>bbb</value>
<!--               <ref bean="xxxx">-->
<!--               <bean class=xxxxx">-->
<!--                   <constructor-arg value="xxx"></constructor-arg>-->
<!--               </bean>-->
           </list>

       </constructor-arg>
    </bean>

🔴Set 类型

用法与list一致,仅需要将xml文件中的list标签改为set标签

🔴Map类型

如果Map集合的值为基本数据类型包装类或String类型,则可通过value属性直接设置;如果为引用类型(如String类型)的数据则可以通过entry 标签的value-ref标签属性(其值为另一个bean标签id或name属性的属性值)或entry 标签bean子标签、ref子标签、list子标签(如果Map集合值为List集合)、set子标签(如果Map集合值为Set集合)或map子标签(如果Map集合值为Map集合)进行设置。

 <bean id = "user9" class="com.yiwu.pojo.User">
    <constructor-arg name="myMap">
        <map>
            <entry key="k1" value="aaa"/>
            <entry key="k2" value="bbb"/>
            <entry key="k3" value="ccc"/>
        </map>
    </constructor-arg>
    </bean>

1.6 Properties

实体类添加private Properties myProperties属性,添加构造方法,更新toString方法

<bean id = "user10" class="com.yiwu.pojo.User">
    <constructor-arg  name="myProperties">
        <props>
            <prop key="key1">aaa</prop>
            <prop key="key2">aaa</prop>
        </props>
    </constructor-arg >
</bean>

2 set方法注入

分析:

​ 在 Spring 实例化 Bean 的过程中,IoC 容器首先会调用默认的构造方法(无参构造方法)实例化 Bean(Java 对象),然后通过 Java 的反射机制调用这个 Bean 的 setXxx() 方法,将属性值注入到 Bean 中。

区别:

  • 使用构造函数依赖注入时,Spring保证所有一个对象所有依赖的对象先实例化后,才实例化这个对象。

  • 使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。

步骤

  1. 在 Bean 中提供一个默认的无参构造函数(在没有其他带参构造函数的情况下),并为所有需要注入的属性提供一个 setter() 方法;
  2. 在applicationContext.xml配置文件中,使用bean标签对bean定义
  3. 在 property标签对各个属性进行赋值。

2.1基本数据类型

简单数据类型字符串。

<bean id = "user11" class="com.yiwu.pojo.User">
    <property name="name" value="张三"></property>
    <property name="sex" value=""></property>
    <property name="age" value="22"></property>
</bean>

2.2自定义类型

  • 方式1:
<bean name="idcard2" class="com.yiwu.pojo.IdCard">
        <property name="code" value="2222222"/>
        <property name="id" value="33"/>
    </bean>
    <bean id = "user12" class="com.yiwu.pojo.User">
        <property name="name" value="张三"/>
        <property name="sex" value=""/>
        <property name="age" value="22"/>
        <property name="idcard" ref="idcard2"/>

    </bean>
  • 方式2:
 <bean id = "user13" class="com.yiwu.pojo.User">
        <property name="name" value="张三"/>
        <property name="sex" value=""/>
        <property name="age" value="22"/>
        <property name="idcard">
            <bean class="com.yiwu.pojo.IdCard">
                <property name="code" value="2222222"/>
                <property name="id" value="33"/>
            </bean>
        </property>

    </bean>

2.3日期类型date

  • 方式1:
<bean id="b2" class="java.util.Date">
    <constructor-arg name="year" value="10"/>
    <constructor-arg name="month" value="11"/>
    <constructor-arg name="date" value="2"/>
</bean>

<bean id = "user14" class="com.yiwu.pojo.User">
   <property name="name" value="张三"/>
   <property name="sex" value=""/>
   <property name="age" value="22"/>
   <property name="brithday" ref="b2"/>
</bean>
  • 方式2:
<bean id = "user15" class="com.yiwu.pojo.User">
        <property name="name" value="张三"/>
        <property name="sex" value=""/>
        <property name="age" value="22"/>

        <property name="brithday">
            <bean class="java.util.Date">
                <constructor-arg name="year" value="10"/>
                <constructor-arg name="month" value="11"/>
                <constructor-arg name="date" value="2"/>
            </bean>
        </property>
    </bean>

2.4集合类型

🔴List

<bean id = "user16" class="com.yiwu.pojo.User">
        <property name="product">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <!-- <ref bean="xxxx">-->
                <!--<bean class=xxxxx">-->
                <!--    <property value="xxx"></property>-->
                <!-- </bean>-->
            </list>

        </property>
    </bean>

🔴Set 类型

用法与list一致,仅需要将xml文件中的list标签改为set标签

🔴Map

<bean id = "user17" class="com.yiwu.pojo.User">
    <property name="myMap">
        <map>
            <entry key="k1" value="aaaa"/>
            <entry key="k2" value="bbbb"/>
            <entry key="k3" value="cccc"/>
        </map>
    </property>
</bean>

2.5 Properties

<bean id = "user18" class="com.yiwu.pojo.User">
    <property  name="myProperties">
        <props>
            <prop key="key1">aaa</prop>
            <prop key="key2">aaa</prop>
        </props>
    </property >
</bean>

3 自动装配

Spring在实例化当前bean的时候自动从Spring容器中找到匹配的实例赋值给当前bean的属性。

创建应用对象之间协作关系的行为称为装配。也就是说当一个对象的属性是另一个对象时,实例化时,需要为这个对象属性进行实例化。这就是装配

依赖注入的本质就是装配,装配是依赖注入的具体行为,这就是两者的关系

创建Product实体类。,在user中添加 Product pd;

package com.yiwu.pojo;

public class Product {
    private String name;
    private double Price;
    
    public Product() {
    }
}
public class User {
    Product pd;   
    //其余省略,与上节内容不变
}

3.1 原始方式

<bean id = "product1" class="com.yiwu.pojo.Product">
    <property name="name" value="java"/>
    <property name="price" value="20"/>
</bean>

<bean id="user19" class="com.yiwu.pojo.User">
    <property name="pd" ref="product1"/>
</bean>

3.2 自动装配

  1. autowire=“byName”
  • 根据当前Bean的属性名,在Spring容器中寻找匹配的对象,如果根据Name找到了bean,但是类型不匹配则会抛出异常

  • bean标签的id值与类的属性名一致

   <bean id = "pd" class="com.yiwu.pojo.Product">
        <property name="name" value="java"/>
        <property name="price" value="20"/>
    </bean>
    <bean id="user19" class="com.yiwu.pojo.User" autowire="byName">
    </bean>
  1. autowire=“byType”

根据当前Bean的属性类型,在spring容器中寻找匹配的对象,如果根据类型找到了多个类型匹配的bean,也会抛出异常。

<bean id = "pd1" class="com.yiwu.pojo.Product">
    <property name="name" value="java"/>
    <property name="price" value="20"/>
</bean>

<bean id="user19" class="com.yiwu.pojo.User" autowire="byType">
 </bean>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老去的90后

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值