【Spring】依赖注入方式,DI的方式

在这里插入图片描述

这里写目录标题

  • 1. setter注入
    • 在一个类中注入引用类型
    • 在一个类中注入简单类型
  • 2. 构造器注入
    • 在一个类中注入引用类型
    • 在一个类中注入简单类型
  • 3. 依赖注入方式选择
  • 4. 依赖自动装配
    • 按类型注入
    • 按名称注入
  • 5. 集合注入

1. setter注入

在一个类中注入引用类型

回顾一下之前setter注入的方法,我们有以下类:
BookDao.java

package com.example.demo.dao;

public interface BookDao {
    void save();
}

BookDaoImpl.java

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

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

BookService.java

package com.example.demo.service;

public interface BookService {
    void save();
}

BookServiceImpl.java

package com.example.demo.service.impl;

import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("book service save...");
    }
}

我们想要将BookDaoImpl注入到BookServiceImpl中,最简单的方法就是通过setter注入
第一步:BookServiceImpl中建立bookDaosetter方法:

package com.example.demo.service.impl;

import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("book service save...");
    }

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

第二步: 配置bookDao,和bookService两个bean(在resource下建立Spring Config文件):

<?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.example.demo.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao" />
    </bean>
</beans>

id属性为bean的名称,class为对应需要注入的类
property表示类里面需要注入的属性,name是属性名称,ref是属性的引用类,这里引用的是上面的bookDao


以上两步即可完成配置,测试一下:

package com.example.demo.service.impl;

import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("book service save...");
        bookDao.save();
    }

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

结果是:

book service save...
book dao save...

在一个类中注入简单类型

假如在上面的BookDaoImpl.java中,还有两个简单类型:

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private int connectNum;
    private String databaseName;

    @Override
    public void save() {
        System.out.println("book dao save...");
        System.out.println("connectNum:" + connectNum + ", databaseName:" + databaseName);
    }
}

第一步: 如果使用setter注入,首先给这两个简单类型写set方法:

public void setConnectNum(int connectNum) {
  this.connectNum = connectNum;
}

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

第二步: 配置的时候,bookDao的配置应该这样写:

<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl">
	<property name="connectNum" value="10"/>
	<property name="databaseName" value="name" />
</bean>

name表示属性的名字,value表示赋予简单类型的值
再执行一下上面写的测试主方法(此处略),结果为:

book service save...
book dao save...
connectNum:10, databaseName:name

总结简单类型的注入:
在这里插入图片描述

2. 构造器注入

在一个类中注入引用类型

BookDao.java

package com.example.demo.dao;

public interface BookDao {
    void save();
}

BookDaoImpl.java

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

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

BookService.java

package com.example.demo.service;

public interface BookService {
    void save();
}

BookServiceImpl.java

package com.example.demo.service.impl;

import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("book service save...");
    }
}

我们想使用构造器注入在bookServiceImpl中注入bookDao,方法如下:
第一步: 在bookServiceImpl中写构造方法

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

第二步: 在配置中配置有参构造方法,通过constructor-arg标签进行构造,也就是向bookDao类型中传入一个什么样的参数

<?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.example.demo.dao.impl.BookDaoImpl"/>

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

再运行主方法,可以获得一样的结果:

book service save...
book dao save...

同样的,假如我们还有一个UserDaoImpl
UserDao.java:

package com.example.demo.dao;

public interface UserDao {
    void save();
}

UserDaoImpl.java:

package com.example.demo.dao.impl;

import com.example.demo.dao.UserDao;

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

我们在BookServiceImpl中还引入了这个类型:

package com.example.demo.service.impl;

import com.example.demo.dao.BookDao;
import com.example.demo.dao.UserDao;
import com.example.demo.service.BookService;

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

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

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

则需要重新写一下构造方法:

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

并多加一行对userDao的配置:

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

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

再次运行测试函数,结果如下:

book service save...
book dao save...
user dao save...

在一个类中注入简单类型

BookDao代码如下:

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private int connectNum;
    private String databaseName;

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

想要给两个简单类型属性做配置,方法都是一样的:
第一步: 创建构造方法

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private int connectNum;
    private String databaseName;

    public BookDaoImpl(int connectNum, String databaseName) {
        this.connectNum = connectNum;
        this.databaseName = databaseName;
    }

    @Override
    public void save() {
        System.out.println("book dao save...");
        System.out.println("connectNum:" + connectNum + ", databaseName:" + databaseName);
    }
}

第二步: 配置属性

<?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.example.demo.dao.impl.BookDaoImpl">
        <constructor-arg name="connectNum" value="10"/>
        <constructor-arg name="databaseName" value="aaa"/>
    </bean>
    <bean id="userDao" class="com.example.demo.dao.impl.UserDaoImpl"/>

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

运行后结果为:

book service save...
book dao save...
connectNum:10, databaseName:aaa
user dao save...

除了通过name指定配置的参数,还有两种办法指定:
我们上面通过name指定的是标准写法
第一种是通过参数类型进行指定(是为了解耦,避免配置和name耦合)
第二种是通过参数位置进行指定(为了解决有同样类型的参数的问题)
在这里插入图片描述

3. 依赖注入方式选择

在这里插入图片描述
建议使用setter注入
第三方技术根据情况选择

4. 依赖自动装配

定义:
在这里插入图片描述
注意,想要让IoC容器实现自动装配,必须给这些属性配置setter方法!

按类型注入

这些属性的类型要能够在配置的bean中的类型对应的上:
在这里插入图片描述
假如配置了两个指向同一类型,id不同的bean,显而易见bookService那里已经报红了:
在这里插入图片描述
如果仍让执行报错会提示,找到了两个bean,不知道匹配哪一个:
在这里插入图片描述
所以bean的类型指向必须唯一!

按名称注入

这些属性的名称要能够在配置的bean中的id对应的上:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5. 集合注入

假设我们的BookDaoImpl.java中有以下的数据类型

package com.example.demo.dao.impl;

import com.example.demo.dao.BookDao;

import java.util.*;

public class BookDaoImpl implements BookDao {

    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    private Properties properties;

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

        System.out.println("遍历数组:" + Arrays.toString(array));

        System.out.println("遍历List:" + list);

        System.out.println("遍历set:" + set);

        System.out.println("遍历Map:" + map);

        System.out.println("遍历properties:" + properties);
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setArray(int[] array) {
        this.array = array;
    }
}

配置文件如下写:

<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl">
        <property name="array">
            <array>
                <value>100</value>
                <value>200</value>
                <value>300</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>a</value>
                <value>b</value>
                <value>c</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>c</value>
                <value>c</value>
                <value>d</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="country" value="china" />
                <entry key="province" value="guangdong" />
                <entry key="city" value="shenzhen" />
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="country">china</prop>
                <prop key="province">henan</prop>
                <prop key="city">kaifeng</prop>
            </props>
        </property>
    </bean>

set是会自动过滤重复元素的,结果如下:

book service save...
book dao save...
遍历数组:[100, 200, 300]
遍历List:[a, b, c]
遍历set:[c, d]
遍历Map:{country=china, province=guangdong, city=shenzhen}
遍历properties:{country=china, province=henan, city=kaifeng}

如果数组里面是引用类型,写法就是:

<property name="array">
    <array>
        <ref bean="beanId" />
    </array>
</property>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/158104.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习实验】网络优化与正则化(七):超参数优化方法——网格搜索、随机搜索、贝叶斯优化、动态资源分配、神经架构搜索

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、优化算法0. 导入必要的库1. 随机梯度下降SGD算法a. PyTorch中的SGD优化器b. 使用SGD优化器的前馈神经网络 2.随机梯度下降的改进方法a. 学习率调整b. 梯度估计修正 3. 梯度估计修正&#xff1a;动量法Momen…

万宾科技智能井盖传感器,提升市政井盖健康

市政井盖就是城市里不可或缺的基础设施之一&#xff0c;关于它的监测工作可马虎不得。它承载着保护市民的交通安全以及城市正常运转的重要使命。虽然现在城市化的速度很快&#xff0c;但是传统的市政井盖管理方式变得有些力不从心了。井盖的覆盖范围很广&#xff0c;如果单单依…

Python爬虫动态ip代理防止被封的方法

目录 前言 一、什么是动态IP代理&#xff1f; 二、如何获取代理IP&#xff1f; 1. 付费代理IP 2. 免费代理IP 3. 自建代理IP池 三、如何使用代理IP爬取数据&#xff1f; 1. 使用requests库设置代理IP 2. 使用urllib库设置代理IP 3. 使用selenium库设置代理IP 四、常…

实现MQTT协议的服务器端和客户端的双向交互

公司和第三方合作开发一个传感器项目&#xff0c;想要通过电脑或者手机去控制项目现场的传感器控制情况。现在的最大问题在于&#xff0c;现场的边缘终端设备接入的公网方式是无线接入&#xff0c;无法获取固定IP&#xff0c;所以常规的HTTP协议通信就没法做&#xff0c;现在打…

群晖7.2安装Jellyfin+alist+CloudDriver搭建无盘影院中心

群晖7.2安装JellyfinalistCloudDriver搭建无盘影音中心。 实现思路如下&#xff1a; Jellyfin&#xff1a;提供个人影院功能。 alist&#xff08;xiaoya&#xff09;&#xff1a;给影院提供海量影音资源。 CloudDriver2&#xff1a;alist的资源为网络资源&#xff0c;通过C…

lvgl 画圆弧时进入 HardFault

目录 一、现象描述 lvgl 版本 二、问题分析 lvgl 需要的资源新建mcu 工程时默认分配的资源问题解决 一、现象描述 移植完lvgl 之后&#xff0c;能正常显示label&#xff0c;但是button arc 等复杂的控件都不能正常显示。调用官方的画圆弧demo 时&#xff0c;在多次调用 _lv…

业务流程图用什么软件画?这10款流程图软件,好用到飞起!

业务流程图是什么&#xff1f; 业务流程图是一种用于表示业务过程中活动流向的图形表示方法&#xff0c;它使用标准化的图形元素&#xff08;如箭头、椭圆、方框等&#xff09;来表达一个过程中各个环节之间的关系。在这个图形表示中&#xff0c;每个元素都有特定的含义和功能…

C#WPF用户控件及自定义控件实例

本文演示C#WPF自定义控件实例 用户控件(UserControl)和自定义控件(CustomControl)都是对UI控件的一种封装方式,目的都是实现封装后控件的重用。 只不过各自封装的实现方式和使用的场景上存在差异。 1 基于UserControl 创建 创建控件最简单一个方法就是基于UserControl …

Docker在Centos7下的安装

1、卸载旧版本 执行如下指令对旧版本进行卸载&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 执行完毕后&#xff0c;如果输入docker version发现do…

【MySQL学习笔记-001】- 创建表、插入数据、查看数据库结构

创建employees表 当创建一个表时&#xff0c;需要指定表的名称和每个列的名称和数据类型。以下是一个示例SQL语句&#xff0c;用于创建一个名为"employees"的表&#xff0c;其中包含员工ID、姓名、职位和工资等列&#xff1a; CREATE TABLE employees (employee_id…

单稳态中间继电器\UEG/A-2H/220V 8A导轨安装 JOSEF约瑟

UEG系列中间继电器 UEG/A-2H2D中间继电器UEG/A-4H4D中间继电器UEG/A-2D中间继电器 UEG/A-2H中间继电器UEG/A-4H中间继电器UEG/A-4D中间继电器 UEG/A-6H中间继电器UEG/A-6D中间继电器UEG/A-8H中间继电器 UEG/A-10D中间继电器UEG/A-10H中间继电器UEG/A-2DPDT中间继电器 UEG/A-4DP…

23111710[含文档+PPT+源码等]计算机毕业设计基于SpringBoot的体育馆场地预约赛事管理系统的设计

文章目录 **软件开发环境及开发工具&#xff1a;****功能介绍&#xff1a;****论文截图&#xff1a;****数据库&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及…

国民技术Cortex-M0系列单片机IAP升级

考虑到设备部署到现场后有可能需要进行软件升级&#xff0c;之前做过PIC系列单片机的升级&#xff0c;现在想做个国民技术N32G031系列Cortex-M0内核的单片机IAP方案。 因为国民技术系列单片机在很多大程度上都模仿了STM32&#xff0c;所以我想其升级方案极有可能差不多。于是在…

C#开发的OpenRA游戏之属性BodyOrientation(6)

C#开发的OpenRA游戏之属性BodyOrientation(6) 在顶层定义里会发现这个属性: ^SpriteActor: BodyOrientation: QuantizeFacingsFromSequence: RenderSprites: SpriteActor是用来定义角色的基本属性,它的第一个属性就是BodyOrientation,这个属性主要用来描述角色的身体的…

DOA估计算法——Capon算法

1.波速形成基本思想 在理解Capon算法之前&#xff0c;我们有必要先了解波束形成的基本思想以及原理到底是什么。这有助于我们更好的理解Capon算法的思想。 图 1 如图1展示了均匀阵列波束导向的示意图。图中wm表示加权值&#xff0c;波速形成(DBF)的基本思想就是将各阵元输出进…

AVL树的底层实现

文章目录 什么是AVL树&#xff1f;平衡因子Node节点插入新节点插入较高左子树的左侧新节点插入较高左子树的右侧新节点插入较高右子树的左侧新节点插入较高右子树的右侧 验证是否为平衡树二叉树的高度AVL的性能 什么是AVL树&#xff1f; AVL树又称平衡二叉搜索树&#xff0c;相…

基于ssm+vue的程序设计课程可视化教学系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Jmeter进行压力测试不为人知的秘密

jmeter是apache公司基于java开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使用方便&#xff0c;是一个比较轻量级的测试工具&#xff0c;使用起来非常简单。因为jmeter是java开发的&#xff0c;所以运行的时候必须先要安装jdk才可以。jmeter是免…

Mysql中的进阶增删查改操作(二)

联合查询和合并查询 一.联合查询1.内连接2.外链接2.1左外连接2.2右外连接 3.自连接4.子查询5.合并查询 一.联合查询 步骤 1.进行笛卡尔积 2.列出连接条件 3.根据需求再列出其他条件 4.针对列进行精简(可以使用聚合函数) 我们先搭建一个多表查询的框架 这样一个多表查询就搭建出…