Spring之DI(依赖注入)

依赖注入(DI)是一个过程,在这个过程中,对象仅通过构造函数参数、工厂方法的参数或在对象被实例化后通过属性设置来定义它们的依赖项(即与该对象一起工作的其他对象)。然后,容器在创建 bean 时注入这些依赖项。这个过程基本上是与对象直接通过构造类或等机制来控制其依赖项的实例化或位置是相反的,因此得名控制反转。// 对象不直接创建自己,而是通过 Spring 容器创建,那么 Spring 容器是如何创建对象的?

使用 DI 原则,代码会更简洁,当对象具有依赖关系时,也能更有效的解耦。对象不检索它的依赖项,也不知道依赖项的具体类或者位置。因此,你的类将变得更容易测试,特别是当依赖关系建立在接口或者抽象基类上时,他们的子类或者模拟实现将允许在单元测试中被使用。// 依赖注入最大的好处,就是代码可以解耦合变得更加简洁

DI 主要有两种变体:基于构造函数的依赖注入和基于 Setter 方法的依赖注入

基础环境

1.创建Module

在这里插入图片描述

2.引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring</artifactId>
        <groupId>com.biem</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>DI</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>
</project>

3. 创建实体类com.biem.spring.pojo.User.java

package com.biem.spring.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * ClassName: User
 * Package: com.biem.spring.pojo
 * Description:
 *
 * @Create 2023/5/25 18:07
 * @Version 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String password;
}

4. 创建applicationContext.xml配置文件

<?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">

</beans>

4. 测试com.biem.spring.test.UserTest.java文件

package com.biem.spring.test;

import com.biem.spring.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * ClassName: UserTest
 * Package: com.biem.spring.test
 * Description:
 *
 * @Create 2023/5/25 18:13
 * @Version 1.0
 */
public class UserTest {

}

基于构造函数的依赖注入

<constructor-arg>元素用于构造方法的注入,且定义时不分顺序,只需要通过name属性指定值即可。<constructor-arg>还提供了type属性用于指定参数类型,以避免字符串和基本类型的混淆。

实例

1.applicationContext.xml添加

    <bean id="user1" class="com.biem.spring.pojo.User">
        <constructor-arg name="id" value="1"></constructor-arg>
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="password" value="123456"></constructor-arg>
    </bean>

2. com.biem.spring.test.UserTest.java添加

    @Test
    public void testConstructorDI(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user1", User.class);
        System.out.println("user = " + user);
    }

3.输出结果

在这里插入图片描述

基于 Setter 方法的依赖注入

setter方法注入是通过<property>元素,<property>元素过name属性指定值。

实例

1.applicationContext.xml添加

    <bean id="user2" class="com.biem.spring.pojo.User">
        <property name="id" value="2"></property>
        <property name="name" value="李四"></property>
    </bean>

2. com.biem.spring.test.UserTest.java添加

    @Test
    public void testSetterDI(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user2", User.class);
        System.out.println("user = " + user);
    }

3.输出结果

在这里插入图片描述

Null值处理

<property name="name">
	<null />
</property>

name的值是null

<property name="name" value="null"></property>

name的值是字符串null

应用:简单登录系统

1.com.biem.spring.dao.UserDao.java

package com.biem.spring.dao;

/**
 * ClassName: UserDao
 * Package: com.biem.spring.dao
 * Description:
 *
 * @Create 2023/5/25 19:45
 * @Version 1.0
 */
public interface UserDao {
    public boolean login(String name, String password);
}

2.com.biem.spring.dao.impl.UserDaoImpl.java

package com.biem.spring.dao.impl;

import com.biem.spring.dao.UserDao;

/**
 * ClassName: UserDaoImpl
 * Package: com.biem.spring.dao.imp
 * Description:
 *
 * @Create 2023/5/25 19:46
 * @Version 1.0
 */
public class UserDaoImpl implements UserDao {
    @Override
    public boolean login(String name, String password) {
        if(name.equals("张三") && password.equals("123")){
            return true;
        }
        return false;
    }
}

3.com.biem.spring.service.UserService.java

package com.biem.spring.service;

/**
 * ClassName: UserService
 * Package: com.biem.spring.service
 * Description:
 *
 * @Create 2023/5/25 21:29
 * @Version 1.0
 */
public interface UserService {
    public boolean login(String username, String password);
}

4.com.biem.spring.service.impl.UserServiceImpl.java

package com.biem.spring.service.impl;

import com.biem.spring.dao.UserDao;
import com.biem.spring.service.UserService;

/**
 * ClassName: UserServiceImpl
 * Package: com.biem.spring.service.impl
 * Description:
 *
 * @Create 2023/5/25 21:31
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    UserDao userDao;

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

    @Override
    public boolean login(String username, String password) {
        return userDao.login(username, password);
    }
}

5.编写applicationContext.xml配置文件

    <bean id="userDao" class="com.biem.spring.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.biem.spring.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

6.编写测试方法

    @Test
    public void login(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService user = context.getBean("userService", UserService.class);
        boolean flag = user.login("张三","123");
        if(flag){
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
    }

在这里插入图片描述

    @Test
    public void login(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService user = context.getBean("userService", UserService.class);
        boolean flag = user.login("张三","1234");
        if(flag){
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
    }

在这里插入图片描述

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

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

相关文章

Hadoop HA(高可用)搭建

ZooKeeper配置 解压安装 添加ZK环境变量 分发文件 启动 安装配置 Hadoop 解压安装 修改hadoop-env.sh文件 修改Hadoop配置文件core-site.xml HDFS 配置文件hdfs-site.xml MapReduce 配置文件 mapred-site.xml YARN 配置文件yarn-site.xml 配置worekers 分发配…

数字孪生智慧路灯可视化系统 区域控制节能增效

前言 智慧灯杆是智慧城市建设的重要组成部分&#xff0c;可以完成照明、公安、市政、气象、环保、通信等行业数据信息的采集、发布和传输。同时&#xff0c;作为5g时代车联网、云网、通信网络建设的重要组成部分&#xff0c;智慧灯杆也将得到广泛应用。 建设背景 城市路灯存…

Python学习笔记——《吴恩达Machine Learning》线性回归例程

文章目录 案例背景线性回归&#xff08;Loss Regression&#xff09;梯度下降法&#xff08;批量梯度下降算法——batch gradient descent&#xff09;计算成本函数和梯度下降使用线性回归拟合训练数据模型预测 梯度下降效果可视化完整版demo 案例背景 详情参照吴恩达机器学习…

linux共享内存总结

共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成 头文件&#xff1a; #include <sys/ipc..h> #include<sys/shm.h> // 创建或获取一个共享内存: 成功返回共享内存ID&#xff0c;失败返回-1 int shmget (key_t key, size_t_size, int flag); // 连接共享内…

相见恨晚的5款良心软件,每款都是经过时间检验的精品

今天来给大家推荐5款良心软件,每款都是经过时间检验的精品,用起来让你的工作效率提升飞快&#xff0c;各个都让你觉得相见恨晚&#xff01; 1.颜色选择器——ColorPicker ColorPicker是一款用于在屏幕上选择颜色的工具。它可以让你快速地获取任意像素的颜色值,并复制到剪贴板…

android aidl及binder基础知识总结

1、什么是binder binder是android framework提供的&#xff0c;用于跨进程方法调用的机制&#xff0c;具有安全高效等特点。 我们知道&#xff0c;在 Android 系统中&#xff0c;每个应用程序都运行在一个独立的进程中&#xff0c;各个进程之间需要进行数据交换和调用&#x…

SolidWorks装配体中让弹簧随装配体运动的方法

弹簧是我们日常设计中最常用的几种零部件之一&#xff0c;但是弹簧不跟螺栓一样装好之后是相对静止的&#xff0c;弹簧在装配好后需要进行运动&#xff0c;在SolidWorks装配体中可以让弹簧跟随其他物体运动&#xff0c;操作分为三大步&#xff1a; 一、创建弹簧&#xff08;使…

三阶段项目

DHCP分配不到冲突地址 需要重启 再分配 用这个命令 reset ip pool name vlan40 all ospf&#xff1a; 建立邻居表&#xff1a;报文&#xff1a;hello报文 状态&#xff1a;down int 2-way 选举DR 同步数据库&#xff1a;报文&#xff1a;DD-LSR-LSU-LSACK 状态&#xff…

分布式协调服务--zookeeper

目录 一、概述 1、zookeeper有两种运行状态 zookeeper架构的角色&#xff1a; 2、Paxos算法&#xff1a;消息传递的一致性算法 3、ZAB协议 Zab 协议实现的作用 Zab协议核心 Zab协议内容 消息广播 崩溃恢复 实现原理 协议实现 一、概述 zookeeper官网 zookeeper官…

神马网络——IP地址

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。座右铭&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石&#xff0c;故能成其高。个人主页&#xff1a;小李会科技的…

transformers两个入门示例

根据《attention is all you need》论文而形成的transformers框架在chat-gpt应用中大放异彩&#xff0c;目前transformers框架已经成了炙手可热的框架。它不仅在nlp方面很作用很大&#xff0c;根据官网的介绍&#xff0c;它还可以做很多事情&#xff0c;比如图片分类&#xff0…

【firewalld防火墙】

目录 一、firewalld概述二、firewalld 与 iptables 的区别1、firewalld 区域的概念 三、firewalld防火墙默认的9个区域四、Firewalld 网络区域1、区域介绍2、firewalld数据处理流程 五、firewalld防火墙的配置方法1、使用firewall-cmd 命令行工具。2、使用firewall-config 图形…

5.24 基础题目

快速幂 #include<bits/stdc.h> using namespace std; //126348976 982638476 938420413 int main(){int a,b,p;cin>>a>>b>>p;long long res 1,ci1;int flag0;if(b0){res%p;}else{while(b){if (flag0)cia%p;elseci(ci%p)*(ci%p)%p;if (b&1)res(res…

吉时利 Keithley 2700数据采集器技术参数

概述&#xff1a; 每个 2700 系列系统均将精密测量、开关和控件集于一个紧凑集成的机箱中&#xff0c;适用于机架安装或台式应用。虽然所有三个系统的核心功能和编程是相同的&#xff0c;但各个主机都具有独特的功能。例如&#xff0c;2701 型具有 10/100BaseTX 以太网接口&am…

面试被问麻了...

前几天组了一个软件测试面试的群&#xff0c;没想到效果直接拉满&#xff0c;看来大家对面试这块的需求还是挺迫切的。昨天我就看到群友们发的一些面经&#xff0c;感觉非常有参考价值&#xff0c;于是我就问他还有没有。 结果他给我整理了一份非常硬核的面筋&#xff0c;打开…

linux0.12-10-1-总体功能

第10章 字符设备驱动程序 [466页] 10-1 总体功能 本章的程序可分成三部分: 第一部分是是关于RS-232串行线路驱动程序&#xff0c;包括程序rs_io.s和serial.c&#xff1b; 第二部分是涉及控制台的驱动程序&#xff0c;包括键盘中断驱动程序keyboard.S和控制台显示驱动程序con…

韦东山Linux驱动入门实验班(2)hello驱动---驱动层与应用层通讯,以及自动产生设备节点

前言 &#xff08;1&#xff09;学习韦东山老师的Linux&#xff0c;因为他讲的很精简&#xff0c;以至于很多人听不懂。接下来我讲介绍韦东山老师的驱动实验班的第二个Hello程序。 &#xff08;2&#xff09;注意&#xff0c;请先学习完视频再来看这个教程&#xff01;本文仅供…

iptables防火墙2

文章目录 iptables防火墙21 SNAT1.1 原理1.2 应用环境1.3 转换前提条件1.4 SNAT转换 2 DNAT2.1 原理2.2 应用环境2.3 转换前提条件 3 SNAT转换3.1 先配置作为网关服务器的虚拟机3.2 修改ens33的网卡3.3 修改ens36的网卡3.4 开启PC2网关服务器的路由转发功能3.5 永久开启3.6 配置…

【Midjourney】Midjourney 辅助工具 ② ( 自定义命令工具 | 设置颜色 | 设置材质 | 设置随机种子 | 设置图片链接 )

文章目录 一、Midjourney Prompt Tool 自定义命令工具1、设置颜色参数2、设置材质参数3、设置随机种子参数4、设置图片链接 Midjourney 提示词命令 可以使用 辅助工具 进行生成 , 辅助工具如下 : Midjourney Prompt Tool 自定义命令工具Midjourney Prompt Generator 命令生成器…

前端开发推荐vscode安装什么插件?

前言 可以参考一下下面我推荐的插件&#xff0c;注意&#xff1a;插件的目的是用于提高开发的效率&#xff0c;节约开发的时间&#xff0c;像类似检查一些bug、拼写错误等这些可以使用插件快速的识别&#xff0c;避免在查找错误上浪费过多的时间&#xff0c;但切记不要过度依赖…