Spring学习记录之依赖注入

问题1:

往一个类中传递数据的方式有哪些呢,其实,只有一种方式,即通过方法,但方法却有多种,一种是我们先前学到的通过set方法(普通方法),另一种则是通过构造方法的方式。

问题2:

依赖注入是描述了容器建立Bean与Bean之间的依赖关系的过程,那么如果Bean运行时需要的是字符串或者其他数据类型而非引用类型(Bean)呢?
那么关于依赖注入的类型也要分为两种,分别是引用类型(Bean)以及String,int等。

Setter方式依赖注入

先前,我们已经使用了set方法来注入引用类型:

<bean id="bookservice"  name="service,books1;bookl books" class="service.impl.BookServiceImpl" ><property name="bookdao" ref="bookdao"></property>
</bean>
public void setBookdao(BookDaoImpl bookdao) {this.bookdao=bookdao;}

那么,如果有多个引用类型呢,我们需要多个setter方法即可。
在BookServiceImpl中定义UserDao接口并实现

UserDao userdao;
public void setUserdao(UserDao userdao) {this.userdao = userdao;}

至于Spring的xml文件中只需要创建一个userdao,随后在bookservice中引用即可。

<bean id="userdao" class="dao.impl.UserDaoImpl" ></bean>
<bean id="bookservice"  name="service,books1;bookl books" class="service.impl.BookServiceImpl" ><property name="bookdao" ref="bookdao"></property><property name="userdao" ref="userdao"></property>
</bean>

那么,该如何注入普通数据类型呢,我们在UserDaoImpl中定义两个私有成员变量:dataBaseNameconnectionNum

package dao.impl;
import dao.UserDao;
public class UserDaoImpl implements UserDao {private String dataBaseName;public void setDataBaseName(String dataBaseName) {this.dataBaseName = dataBaseName;}public void setConnectionNum(int connectionNum) {this.connectionNum = connectionNum;}private int connectionNum;@Overridepublic void save() {System.out.print("userdao ..."+connectionNum+","+dataBaseName+"\n");}
}

随后在xml文件中注入属性值:使用property标签中的value属性来注入基本数据类型。

<bean id="userdao" class="dao.impl.UserDaoImpl" ><property name="connectionNum" value="10"></property><property name="dataBaseName" value="mysql"></property>
</bean>

运行结果如下:

在这里插入图片描述

构造器方式依赖注入

接下来,上面是通过setter方法来进行依赖注入,另一种方法则是通过构造方法的形式进行依赖注入,事实上,两种写法很相似,但由于采用构造方法进行依赖注入时会有些许问题,因此我们大多采用setter方法来进行依赖注入。

在这里插入图片描述

在这里插入图片描述
由于构造器传参的方式要求Spring中属性的name必须与构造函数中的形参保持一致,因此具有一定的耦合度,这就导致Spring中提供了根据type类型与index属性来进行注入,但依旧很不方便,因此我们多采用Setter方法的方式进行注入。然而,仍存在些许情况我们需要使用构造器注入的方式:

在这里插入图片描述

依赖自动装配

前面已经介绍了两种依赖注入方式,但这些都需要我们自己去写,那么,这个依赖注入的方法能够不写呢,当然可以,Spring由此提出了依赖自动装配。
IOC根据Bean所依赖的资源在容器中自动查找并注入到Bean的过程称为依赖自动装配。
有两种主要的自动装配方式,分别是按照类型装配以及按照类型装配,其中按照类型装配最为常用。
首先,在ServiceImpl中的set方法还是需要保留的,这也符合Spring的装配策略,保证不易出错。
按名称装配:

package service.impl;import dao.BookDao;
import dao.impl.BookDaoImpl;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import service.BookService;public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {BookDao bookdao;UserDao userdao;public void save() {System.out.print("执行service...\n");bookdao.save();}public void setBookdao(BookDaoImpl bookdao) {this.bookdao=bookdao;}
}

可以看到使用按名称自动装配时只需要使用autowire属性即可,这里的名称值得是在service中定义的成员变量bookdao,事实上,其真正对应的是set方法去掉set后第一个字母小写的名称即bookdao。

<bean id="bookservice" class="service.impl.BookServiceImpl" autowire="byName"></bean>

而按类型装配则更为简单了,它甚至都不需要依赖类有名字,会装配所有需要的,符合的Bean,这种也是最常用的。注意:里面对应的setter方法是需要保留的。

<bean id="bookdao" class="dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"></bean>
<bean  class="dao.impl.UserDaoImpl" ><property name="connectionNum" value="10"></property><property name="dataBaseName" value="mysql"></property>
</bean>
<bean id="bookservice" class="service.impl.BookServiceImpl" autowire="byType"></bean>

在这里插入图片描述

集合注入

package dao.impl;
import dao.OrderDao;
import java.util.*;
public class OrderDaoImpl implements OrderDao {private List<String> list;private Map<String,String> map;private Set<String> set;private int[] array;public void setList(List<String> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}public void setSet(Set<String> set) {this.set = set;}public void setArray(int[] index) {this.array = index;}public void setProperties(Properties properties) {this.properties = properties;}private Properties properties;@Overridepublic void show() {     System.out.print(Arrays.toString(array)+"\n"+map+"\n"+set+"\n"+list+"\n"+properties+"\n");}
}
<bean id="orderdao" class="dao.impl.OrderDaoImpl"> <property name="map"><map><entry value="100" key="apple"></entry><entry value="40" key="orange"></entry><entry value="130" key="dog"></entry></map></property><property name="array"><array><value>100</value><value>200</value></array></property><property name="list"><list><value>dog</value><value>cat</value></list></property><property name="set"><set><value>100</value><value>100</value><value>200</value></set></property><property name="properties"><props><prop key="country">china</prop><prop key="city">beijing</prop></props></property>
</bean>

运行结果:

在这里插入图片描述

数据源等对象(第三方资源)管理

先前的都是我们对自己创建的对象Bean进行管理,那么对于一些第三方资源如何管理呢?
这里我们以数据库连接池c3p0为例,首先在pom.xml文件中加入c3p0的坐标:

<dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version>
</dependency>

随后在IOC容器中配置Bean,我们可以在浏览器中搜索c3p0的连接池Bean使用哪个类进行创建,随后我们进入该类中,按Alt+7调出该类的所有方法,从而确定我们是使用setter还是构造函数的方式来创建Bean。

 <bean class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean>

我们通过查看其方法发现其提供的是通过setter方法来传递参数,我们将其配置完成。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc\:mysql\:///ssm_takeout?characterEncoding=utf-8"/><property name="user" value="root"/><property name="password" value="root"/>
</bean>

随后运行一下:

ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource= (DataSource) ctx.getBean("dataSource");
System.out.print(dataSource);

在这里插入图片描述
但是,我们直接将配置信息写在IOC容器中是不合适的,我们应该使用Properties文件来读取到Bean中进而生成配置。那么如何使用Spring加载外部文件呢?Spring 使用开启命名空间的方式来加载外部文件。
在头文件上加上下面三句代码:
1.开启context命名空间
在这里插入图片描述

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"
>

随后使用context命名空间加载properties文件并通过属性占位符$读取数据
这里只要我们使用context加载完文件后,那么${jdbc.driver}便可以在整个IOC容器中使用。

<context:property-placeholder location="db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/>
</bean>

此外,需要注意的是,在加载文件时,如果properties文件中的变量与一些系统变量重复了,那么由于系统变量优先级较高,则会覆盖我们设置的变量,此时,我们只需要在添加一个属性system-properties-mode="NEVER"即可,代表不加载系统变量。

 <context:property-placeholder location="db.properties" system-properties-mode="NEVER"/>

同时,如果想要加载多个properties文件,只需要在location属性中通过逗号连接即可。

<context:property-placeholder location="db.properties,db.properties1" system-properties-mode="NEVER"/>

但这样的加载方式也太过麻烦,我们可以使用*.properties来匹配所有的配置文件。

<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>

但最规范的格式应加上classpath

<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>

但这种方式只能在自己的项目中读取,要想在引用的jar包中读取则可使用:

<context:property-placeholder location="classpath*:db.properties" system-properties-mode="NEVER"/>

在这里插入图片描述

容器

这里我们对容器内容进行补充:其中第一种是根据类路径加载配置文件,第二种则是根据绝对路径加载配置配件,我们多采用第一种。
在这里插入图片描述

在这里插入图片描述
需要注意的是,创建容器的方式有两种分别是通过BeanFactory与ApplicationContext,我们常用的是后者,其加载方式是立即加载,即在创建容器时便将Bean创建好了,而还有一种方式则是 在我们需要才创建Bean,称为延迟加载,如何实现呢?加上lazy-init属性即可

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" lazy-init="true">

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫-数据采集和处理

文章目录 数据数据类型 数据分析过程数据采集数据采集源数据采集方法 数据清洗清洗数据数据集成数据转换数据脱敏 数据 《春秋左传集解》云&#xff1a;“事大大其绳&#xff0c;事小小其绳。”体现了早期人类将事情的“大小”这一性质抽象到“绳结大小”这一符号上从而产生数…

【单点知识】基于实例讲解PyTorch中的Transforms类

文章目录 0. 前言1. 基本用法1.1 转换为Tensor1.2 图像大小调整1.3 随机裁剪1.4 中心裁剪1.5 随机翻转1.6 随机旋转1.7 填充1.8 组合变换 2. 进阶用法2.1 归一化2.2 色彩空间转换2.3 颜色抖动2.4 随机仿射2.5 透视变换2.6 自定义变换 0. 前言 按照国际惯例&#xff0c;首先声明…

Day51-Nginx多实例知识与大厂企业级实战

Day51-Nginx多实例知识与大厂企业级实战 1. 什么是nginx多实例&#xff1f;2. 为什么要用多实例&#xff1f;3. 大厂数百个业务项目&#xff0c;如何来管理&#xff1f;4. 大厂上百项目web分用户解决方案4.1 编译nginx环境实践&#xff1a;4.2 zuma实例(利用普通用户权限将不同…

前端项目,个人笔记(二)【Vue-cli - 引入阿里矢量库图标 + 吸顶交互 + setup语法糖】

目录 1、项目中引入阿里矢量库图标 2、实现吸顶交互 3、语法糖--<script setup> 3.1、无需return 3.2、子组件接收父组件的值-props的使用 3.3、注册组件 1、项目中引入阿里矢量库图标 步骤一&#xff1a;进入阿里矢量库官网中&#xff1a;iconfont-阿里巴巴矢量…

教务管理系统(java+mysql+jdbc+Druid+三层架构)

1、项目要求 1.1数据库表描述 设计一个教务管理系统&#xff0c;要求如下&#xff1a; 系统涉及的表有 account表&#xff08;账号表&#xff09; teacher表&#xff08;教师表&#xff09; student表&#xff08;学生表&#xff09; course表 (课程表) score表&#xff08;成…

Python内置对象

Python是一种强大的、动态类型的高级编程语言&#xff0c;其内置对象是构成程序的基础元素。Python的内置对象包括数字、字符串、列表、元组、字典、集合、布尔值和None等&#xff0c;每种对象都有特定的类型和用途。 01 什么是内置对象 这些对象是编程语言的基础构建块&…

STP环路避免实验(思科)

华为设备参考&#xff1a;STP环路避免实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 Spanning Tree Protocol&#xff08;STP&#xff09;&#xff0c;即生成树协议&#xff0c;是一种数据链路层协议。主要作用是防止二层环路&#xff0c;并自适应网络变化和故障…

Unity2D实现鼠标拖动物体移动(简单好抄)

1.新建脚本&#xff0c;并将脚本拖到你想要拖动的物体上即可 using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine;public class text : MonoBehaviour {private Vector3 offset;public int x 1;void OnMouseDown(…

SAP前台处理:物料主数据创建<MM01>之销售视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

matlab软件基础

第1讲 MATLAB初步 MATLAB是矩阵实验室&#xff08;Matrix Laboratory&#xff09;的简称&#xff0c;是美国MathWorks公司出品的商业数学软件&#xff0c;用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境。MATLAB和Mathematica、Maple并称为三…

Linux 发布项目到OpenEuler虚拟机

后端&#xff1a;SpringBoot 前端&#xff1a;VUE3 操作系统&#xff1a;Linux 虚拟机&#xff1a;OpenEuler 发布项目是需要先关闭虚拟机上的防火墙 systemctl stop firewalld 一、运行后端项目到虚拟机 1、安装JDK软件包 查询Jdk是否已安装 dnf list installed | grep jd…

Redis数据结构对象中的类型检查与命令多态、内存回收

类型检查与命令多态 概述 redis中用于操作键的命令基本上可以分为两种类型。其中一种命令可以对任何类型的键执行&#xff0c;比如说DEL命令、EXPIRE命令、RENAME命令、TYPE命令、OBJECT命令等. 而另一种命令只能对特定类型的键执行&#xff0c;比如说 1.SET、GET、APPEND、…

OPTEE v3.20.0 FVP环境搭建

目录 一、前提条件 二、下载fvp代码 三、下载工具链 四、下载Foundation_Platform FVP平台 五、编译及运行 一、前提条件 1、安装如下的依赖工具 sudo apt-get install android-tools-adb android-tools-fastboot autoconf \ automake bc bison build-essential ccache c…

windows管理github代码

资料 windows SSH下载github

51单片机—AD/DA

目录 1.AD/DA元件介绍 2.运算放大器 3.原理分析 4.性能指标 5.内部芯片时序 6.程序实操 7.原理图 1.AD/DA元件介绍 一般传感器的值会随参数的值变化&#xff0c;AD一般对电压进行转换&#xff0c;AD有多个通道&#xff0c;但是DA只有一个通道&#xff0c;且AD的运用较为广…

路由器怎么做端口映射

路由器在网络中起到了连接不同设备和提供网络服务的重要作用。端口映射是一项常见的操作&#xff0c;它允许外部网络中的设备通过路由器访问内部网络中的设备。我们将介绍如何在路由器上进行端口映射的设置。 理解端口映射 在开始操作之前&#xff0c;我们需要了解一些基本概念…

反射 Reflection

反射 反射的概念 反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息(比如成员变量&#xff0c;构造器&#xff0c;成员方法等等)&#xff0c;并能操作对象的属性及方法。反射在设计模式和框架底层都会用到加载完类之后&#xff0c;在堆中就产生了一个Class类型…

Flutter 在 Windows 下的开发环境搭建(Flutter SDK 3.19.2)【图文详细教程】

Git 下载与安装 对于 Flutter 3.19&#xff0c;Git 版本需要 2.27 及以上 Git 下载&#xff1a; Git 官网&#xff1a;https://git-scm.com/Git 下载淘宝镜像&#xff1a;https://registry.npmmirror.com/binary.html?pathgit-for-windows/ 对于 Git 的安装教程&#xff0c;…

Python分析无人驾驶汽车在桂林市文旅行业推广的问卷

【项目背景】 通过市场调研、文本分析、访谈和问卷调查等方法&#xff0c;探讨&#xff1a; 网民对无人驾驶汽车出行服务的态度。无人驾驶安全员的行业背景。不同人群在旅游时的交通选择偏好。游客及当地居民对桂林市文旅路线的交通满意度。乘客对无人驾驶汽车的满意度。桂林…

超快速排序(蓝桥杯,归并排序,acwing)

题目描述&#xff1a; 在这个问题中&#xff0c;您必须分析特定的排序算法----超快速排序。 该算法通过交换两个相邻的序列元素来处理 n 个不同整数的序列&#xff0c;直到序列按升序排序。 对于输入序列 9 1 0 5 4&#xff0c;超快速排序生成输出 0 1 4 5 9。 您的任务是确…