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

文章目录

    • 1 构造方法注入
      • 1.1 基本数据类型
      • 1.2 拓展Lombok
      • 1.3 自定义类型
      • 1.4 日期类型date
      • 1.5 集合类型
      • 1.6 Properties
    • 2 set方法注入
      • 2.1基本数据类型
      • 2.2自定义类型
      • 2.3日期类型date
      • 2.4集合类型
      • 2.5 Properties
    • 3 自动装配
      • 3.1 原始方式
      • 3.2 自动装配

  • 依赖注入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.projectlombokgroupId>
    <artifactId>lombokartifactId>
    <version>1.18.24version>
    <scope>providedscope>
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对象同样利用其构造方法。

三、Spring中的依赖注入与自动装配_第1张图片

<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>aaavalue>
               <value>bbbvalue>




           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">aaaprop>
            <prop key="key2">aaaprop>
        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>aaavalue>
                <value>bbbvalue>
                
                
                
                
            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">aaaprop>
            <prop key="key2">aaaprop>
        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>

你可能感兴趣的:(Spring系列教程,spring,java)