2.spring框架-----spring framework DI依赖注入

本文详细介绍了Spring框架中的依赖注入(DI)原理,包括setter注入和构造器注入两种方式。setter注入涉及引用类型和简单类型的注入,而构造器注入则演示了单个和多个参数的注入,包括引用类型和基本类型。通过实例代码展示了如何在XML配置文件中进行注入配置,并讨论了构造函数参数变化时的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、DI依赖注入

1.setter注入

 1.1setter引用类型注入 

 1.2setter简单类型注入

2.构造器注入

2.1构造器引用类型注入 

2.2构造器多个引用类型注入 

2.3构造器多个基本类型注入 


一、DI依赖注入

Spring提供了两种注入方式,分别是:

setter注入 简单类型 引用类型

构造器注入 简单类型 引用类型

1.setter注入

添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和 BookServiceImpl类

public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("user dao save ...");
    }
}

public interface BookService {
    public void save();
}

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

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

xml文件 

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>

运行文件 

public class AppForLifeCycle {
    public static void main( String[] args ) {
        ApplicationContext ctx = new
                ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }

}

 1.1setter引用类型注入 

在BookServiceImpl中声明userDao属性,并提供setter方法

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }

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

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

在applicationContext.xml配置文件中使用property标签注入 

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
</bean>

 1.2setter简单类型注入

1.在BookDaoImpl类中声明对应的简单数据类型的属性

2.为这些属性提供对应的setter方法

3.在applicationContext.xml中配置

在BookDaoImpl类中声明对应的简单数据类型的属性,并提供对应的setter方法

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;

    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
    public void save() {
        System.out.println("book dao save..."+databaseName+","+connectionNum);    
    }
}

在applicationContext.xml配置文件中使用property标签注入

  <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <property name="databaseName" value="mysql"/>
        <property name="connectionNum" value="10"/>
    </bean>
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"></property>
        <property name="userDao" ref="userDao"></property>
    </bean>

value:后面跟的是简单数据类型,对于参数类型,Spring在注入的时候会自动转换,但是不能写成英文,spring在将英文转换成int类型的时候就会报错。

引用数据类型使用的是 <property name="" value=""/>

简单数据类型使用的是 <property name="" ref=""/>

2.构造器注入

项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和 BookServiceImpl类

public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;

    public void save() {
        System.out.println("book dao save...");
    }
}

public interface UserDao {
    public void save();
}


public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("user dao save ...");
    }
}

public interface BookService {
    public void save();
}

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

xml文件 

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>

运行文件 

public class AppForLifeCycle {
    public static void main( String[] args ) {
        ApplicationContext ctx = new
                ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }

}

2.1构造器引用类型注入 

1.添加带有bookDao参数的构造方法

2.在applicationContext.xml中配置

在BookServiceImpl类中添加带有bookDao参数的构造方法

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

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

在applicationContext.xml中配置

 <constructor-arg name="" ref=""/>

name属性对应的值为构造函数中方法形参的参数名,必须要保持一致。

ref属性指向的是spring的IOC容器中其他bean对象。

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

2.2构造器多个引用类型注入 

在BookServiceImpl声明多个类并提供多个参数的构造函数

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;
    
    public BookServiceImpl(BookDao bookDao,UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }
    
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    <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 name="userDao" ref="userDao"/>
    </bean>

2.3构造器多个基本类型注入 

1.提供一个包含这两个参数的构造方法

2.在applicationContext.xml中进行注入配置

修改BookDaoImpl类,添加构造方法

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;
    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
    }
    public void save() {
        System.out.println("book dao save..."+databaseName+","+connectionNum);
    }
}

在applicationContext.xml中进行注入配置 

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

 

当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变 

方式一:删除name属性,添加type属性,按照类型注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg type="int" value="10"/>
<constructor-arg type="java.lang.String" value="mysql"/>
</bean>

这种方式可以解决构造函数形参名发生变化带来的耦合问题 但是如果构造方法参数中有类型相同的参数,这种方式就不友好了

方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg index="1" value="100"/>
<constructor-arg index="0" value="mysql"/>
</bean>

这种方式可以解决参数类型重复问题 但是如果构造方法参数顺序发生变化后,这种方式又带来了耦合问题

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学习java的张三

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

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

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

打赏作者

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

抵扣说明:

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

余额充值