Spring的Set注入和构造注入(赋值)

1 什么是注入

1.1 为什么需要注入

注入:通过Spring的配置文件,为成员变量赋值
Set注入:Spring调用Set方法 通过配置文件 为成员变量赋值
构造注入:Spring调用构造方法 通过配置文件 为成员变量赋值

在这里插入图片描述

1.2 注入的好处

解耦合
属性的值都写在xml配置文件里面, 以后修改可以直接修改xml文件里面的内容,代码层面不需要修改

2 Set注入详解

2.1 Set注入的原理分析(简易版)

Spring通过底层调用对象属性对应的set方法,完成成员变量的赋值,
这种方式我们也称之为
set注入****
在这里插入图片描述

2.2如何进行Set注入[开发步骤]
  • 类的成员变量提供set get方法
  • 配置spring的配置文件applicationContext.xml
    properties name 要和类的属性名一致
    properties name 要和类的属性名一致
 <bean id="person" class="com.baizhiedu.basic.Person">
   <property name="id">
     <value>10</value>
   </property>
   <property name="name">
     <value>xiaojr</value>
   </property>
</bean>
2.3成员变量的不同类型

在这里插入图片描述
标签代表调用变量的set方法,针对于不同类型的成员变量,在标签里面,需要嵌套其他标签

<property>
    xxxxx
</property>
2.4 JDK内置类型
2.4 .1 String+8种基本类型
<value>suns</value>
2.4 .2 数组

目标赋值成员变量:

private String[] emails;

赋值方式:

<property name="emails">
      <list>
          <value>huosiyan@qq.com</value>
          <value>xuguanghan@qq.com</value>
          <value>dilireba@qq.com</value>
      </list>
 </property>
2.4 .3 Set集合(无序)

目标赋值成员变量:

private Set<String> phone;

赋值方式:

<property name="phone">
      <set>
          <value>15633339999</value>
          <value>15633339988</value>
          <value>15633339977</value>
          <value>15633339999</value>
      </set>
</property>

注意: Set集合最核心的标签是,里面存什么是根据set的泛型来的, 如果没有指定泛型, 标签里面就什么都可以放,例如
目标赋值成员变量(没有给set集合设置泛型):

private Set message;

赋值方式(set里面除了能存基本类型,也可以嵌套set,或者用户的自定义类型等等):

<property name="message">
      <set>
          <value>1111</value>
          <set></set>
          <list></list>
          <ref bean=""/>
      </set>
</property>
2.4.4 List集合(有序)

目标赋值成员变量:

 private List<String> address;

赋值方式:

<property name="address">
      <list>
          <value>1111</value>
          <value>浙江杭州</value>
          <value>江苏南京</value>
          <value>安徽合肥</value>
      </list>
</property>

注意: 和set类似,list集合最核心的标签是 里面存什么是根据set的泛型来的, 如果没有指定泛型, 标签里面就什么都可以放

<list>
   <ref bean
   <set 
</list>
2.4.5 Map集合

目标赋值成员变量:

private Map<String,String> family;

赋值方式:
一个entry标签代表一个键值对,
key需要用特定的标签 包起来,,
值根据对应类型选择对应类型的标签

<property name="family">
            <map>
                <entry>
                    <key><value>父亲</value></key>
                    <value>13699996666</value>
                </entry>
                <entry>
                    <key><value>母亲</value></key>
                    <value>16333333333</value>
                </entry>
            </map>
        </property>

注意: Map集合最核心的标签是 ,里面存什么是根据map的泛型来的, 如果没有指定泛型,标签里面就什么都可以放

<map>
  <entry>
    <key><value>chenyn</value></key>
    <ref bean
  </entry>
</map>
2.4.6 Properties集合

目标赋值成员变量:

 private Properties p;

赋值方式:

<property name="p">
    <props>
        <prop key="userName">张三</prop>
        <prop key="password">zhangsan</prop>
    </props>
</property>

注意: Properties集合里面存的只能是字符串类型,不会出现其它类型的情况, 所以省略了标签不写

2.5 自定义类型

例如:UserService的实现类里面需要调用 UserDao访问数据库,通过Spring的方式完成成员注入,先声明UserDao成员变量,然后为成员变量提供set get方法
(提示:要想为UserService的成员变量UserDao赋值,需要先创建UserService对象)

public class UserServiceImpl implements UserService {
    
    private UserDao userDao;

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void register(User user) {
        userDao.save(user);
    }

    @Override
    public void login(String name, String password) {
        userDao.queryUserByNameAndPassWord(name,password);
    }
}
2.5.1 第一种方式

配置文件中进行注入(赋值)

<bean id="userService" class="com.tcgroup.service.UserServiceImpl">
    <property name="userDao">
        <bean class="com.tcgroup.Dao.UserDaoImpl"/>
    </property>
</bean>


2.5.2 第二种方式
  • 第一种赋值方式存在的问题
  1. 配置文件代码冗余
  2. 被注入的对象(UserDAO),多次创建,浪费(JVM)内存资源
    在这里插入图片描述
  • 第二种方式:先创建好UserDao对象,userService调用userDao的时候 直接用标签调用即可
<bean id="userDao" class="com.tcgroup.Dao.UserDaoImpl"/>
    
    <bean id="userService" class="com.tcgroup.service.UserServiceImpl">
        <property name="userDao">
            <ref bean="userDao"/>
        </property>
    </bean>
    <bean id="orderService" class="com.tcgroup.service.OrderServiceImpl">
        <property name="userDao">
            <ref bean="userDao"/>
        </property>
    </bean>
    

3. Set注入的简化写法

3.1 基于属性简化

8种基本类型+String类型的属性注入标签 也就是value标签简化

<property name="age">
    <value>10</value>
</property>

<property name="age" value="10"/>

用户自定义类型的引用简化:

<bean id="userService" class="com.tcgroup.service.UserServiceImpl">
    <property name="userDao">
        <ref bean="userDao"/>
    </property>
</bean>

   <bean id="userService" class="com.tcgroup.service.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>
3.2 基于p命名空间简化

先在bean标签里面引入p命名空间,先写一个“p:” 然后按ALT+回车引入,在xml文件最上面可以看到xmlns:p=“http://www.springframework.org/schema/p”
在这里插入图片描述
8种基本类型+String类型的属性注入原来的写法:

<bean id="person" class="com.tcgroup.entity.Person">
<!--    基于属性的简化写法    -->
    <property name="age" value="10"/>
    <property name="name">
        <value>张三</value>
    </property>
</bean>

通过P命名空间简化之后

 <bean id="person" class="com.tcgroup.entity.Person" p:name="张三" p:age="10" />

用户自定义类型的引用之前的写法:

  <bean id="userService" class="com.tcgroup.service.UserServiceImpl">
        <property name="userDao">
            <ref bean="userDao"/>
        </property>
    </bean>

通过P命名空间简化之后

<bean id="userService" class="com.tcgroup.service.UserServiceImpl" p:userDao-ref="userDao"/>

4. 构造注入

4.1. 开发步骤
  • 提供有参构造方法
public class Customer implements Serializable {
    private String name;
    private int age;
    private String gender;

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

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

    @Override
    public String toString() {
        return "Customer{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • Spring的配置文件(applicationContext.xml)
    通过标签赋值, 一个标签对应一个属性,顺序需要和构造参数的顺序一致
<bean id="customer" class="com.tcgroup.entity.Customer">
    <constructor-arg>
        <value>张三三</value>
    </constructor-arg>
    <constructor-arg>
        <value>12</value>
    </constructor-arg>
    <constructor-arg>
        <value></value>
    </constructor-arg>
</bean>
4.2 构造方法重载

2.1 参数个数不同时
参数个数不同时,Spring会根据构造方法的形参个数来确定调用哪个构造方法,

2.2 构造参数个数相同时
但是如果有两个构造方法的形参个数相同,且都是用同一个标签赋值时, 我们需要在XML文件里面通过在标签引入 type属性 进行类型的区分

public Customer(String name) {
        this.name = name;
    }

    public Customer(int age) {
        this.age = age;
    }
    <bean id="customer" class="com.tcgroup.entity.Customer">
        <constructor-arg type="int">
            <value>12</value>
        </constructor-arg>
    </bean>

constructor-arg标签里面还有很多其他属性,可以参加下面这位大佬的博文介绍
https://blog.csdn.net/S_Tian/article/details/103824017

实战大量应用的是set注入,因为构造方法重载麻烦,且Spring底层也大量应用了Set注入

5.反转控制和依赖注入

5.1 反转控制概念在这里插入图片描述

反转(转移)控制(IOC Inverse of Control)

控制:对于成员变量赋值的控制权
反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中完成
   好处:解耦合
底层实现:工厂设计模式
5.2 依赖注入 (Dependency Injection DI)

依赖注入是一种Spring的编程方式

注入:通过Spring的工厂及配置文件,为对象(bean,组件)的成员变量赋值

依赖注入:当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,最终通过Spring配置文件进行注入(赋值)。
好处:解耦合

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值