Spring 依赖注入方式(setter与构造器)依赖注入方式选择,构造器注入的参数适配

1.问题思考(1):向一个类中传递数据的方式有几种?

setter方法

构造方法

2.问题思考(2):依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程,如果bean运行需要的是数字或者字符串呢?

引用类型

简单类型(基本数据类型与String)

3.问题思考(3):依赖注入方式有几种?

(1)setter注入

简单类型

引用类型

(2)构造器注入

简单类型

引用类型

setter方法注入 

一,多种引用数据类型的情况下,(包含单个引用数据类型的情况下)

1.在bean中定义引用类型属性,并提供可访问的set方法

package com.itheima.service.impl;

import com.itheima.dao.BookDao;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class BookServiceImpl implements BookService{

    private BookDao bookDao;
    private UserDao userDao;

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

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void save() {
        System.out.println("Service save.....");
    }
}

2.在Spring配置文件上使用property标签ref属性注入引用类型对象 

<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

    <!--
    多个引用类型的形况下
    name是service的变量名
    ref写已有的bean,也就是上方的bean
    -->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"></property>
        <property name="userDao" ref="userDao"></property>
    </bean>

</beans>

 二,多种普通数据类型的情况下,(String与Integer)

1.在bean中定义引用类型属性,并提供可访问的set方法

package com.itheima.dao.impl;

import com.itheima.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private Integer connectionNumber;
    private String databaseName;

    public void setConnectionNumber(Integer connectionNumber) {
        this.connectionNumber = connectionNumber;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public void save() {
        System.out.println("bookDao save ..."+connectionNumber+","+databaseName+"");
    }
}

2.在Spring配置文件上使用property标签value属性内写入值,Spring会自动识别

<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <property name="databaseName" value="mysql"></property>
        <property name="connectionNumber" value="100000"></property>
    </bean>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

    <!--
    多个引用类型的形况下
    name是service的变量名
    ref写已有的bean,也就是上方的bean
    -->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"></property>
        <property name="userDao" ref="userDao"></property>
    </bean>

</beans>

构造器注入

一,多种  引用数据类型的情况下,(包含单个引用数据类型的情况下)

1.在bean中定义引用类型属性,并提供可访问的构造方法

package com.itheima.service.impl;

import com.itheima.dao.BookDao;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class BookServiceImpl implements BookService {

    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }

    @Override
    public void save() {
        System.out.println("Service save.....");
        bookDao.save();
        userDao.save();
    }
}

2.在Spring配置文件上使用constructor-arg标签ref属性注入引用类型对象,Spring会自动识别

<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>


    <!--
    name指的是构造函数中的形参的名称
    ref指的还是上方的bean对象
    -->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

</beans>

二,多种普通数据类型的情况下,(String与Integer)

1.在bean中定义引用类型属性,并提供可访问的构造方法(dao)

package com.itheima.dao.impl;

import com.itheima.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private Integer connectionNumber;
    private String databaseName;

    public BookDaoImpl(Integer connectionNumber, String databaseName) {
        this.connectionNumber = connectionNumber;
        this.databaseName = databaseName;
    }

    public void save() {
        System.out.println("bookDao save ..."+connectionNumber+","+databaseName+"");
    }
}

2.在Spring配置文件上使用constructor-arg标签Value属性给普通数据类型赋值,Spring会自动识别

name指的是构造函数中的形参的名称
ref指的还是上方的bean对象

<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <constructor-arg name="connectionNumber" value="10000"></constructor-arg>
        <constructor-arg name="databaseName" value="mysql"></constructor-arg>
    </bean>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>


    <!--
    name指的是构造函数中的形参的名称
    ref指的还是上方的bean对象
    -->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

</beans>

问题:我们在dao层定义了一个databaseName的基本数据类型进行注入,但是当databaseName更换了名字之后,我们就发现,耦合度太高,以至于我们在配置文件上也得发生改变,所以要进行解耦

构造器注入----参数适配

第一种方式(标准书写)

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
            <constructor-arg name="connectionNumber" value="10000"></constructor-arg>
            <constructor-arg name="databaseName" value="mysql"></constructor-arg>
        </bean>
        <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

        <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
            <constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
            <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>

第二种方式(按照顺序和数据类型进行参数适配)

解决了形参名称的问题,与形参名称不耦合了

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
            <constructor-arg type="java.lang.Integer" value="10000"></constructor-arg>
            <constructor-arg type="java.lang.String" value="mysql"></constructor-arg>
        </bean>
        <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
        <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
            <constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
            <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>

第三种方式(按照索引与数据类型进行参数适配)我认为是最好用的

解决参数类型重复问题,使用位置来解决参数的匹配

 <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <constructor-arg type="java.lang.Integer" index="0" value="10000"></constructor-arg>
        <constructor-arg type="java.lang.String" index="1" value="mysql"></constructor-arg>
    </bean>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

依赖注入方式选择

1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现

2.可选依赖使用setter诸如进行,灵活性强

3.Spring框架倡导使用构造器,第三方框架内部大多数采用构造器的形式进行数据的初始化,相对严谨

4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入

5.实际开发的过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器开发

6.自己开发的模块,推荐使用setter注入

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

看到我,请让我去学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值