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,一经查实,立即删除!

相关文章

【Greenhills】MULTI IDE-GHS最新版本Compiler 23.5.4的兼容性问题

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 关于GHS推出的最新编译器版本 Compiler 2023.5.4在GHS以前版本的MULTI IDE上面能否使用的问题 2、 问题场景 针对于&#xff0c;客户使用MULTI IDE 8.1.4以前的IDE版本&#xff0c;想要搭载使用最新版本的编译器…

c++ 模拟 三维数组输入 string转化为int

// 函数用于将字符串解析为三维数组 vector<vector<vector<int>>> parseString3(string& input) { //[[[0,1,0,0,2],[1,2,1,2,1],[1,0,1,0,0],[0,1,2,0,0],[1,1,0,0,2]]] vector<vector<vector<int>>> result1; vector<…

Python爬虫-数据采集和处理

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

(保姆级)离线安装mongoDB集群

Docker搭建MongoDB集群 副本集模式&#xff08;Replica Set&#xff09; 是一种互为主从的关系&#xff0c; Replica Set 将数据复制多份保存&#xff0c;不同服务器保存同一份数据&#xff0c;在出现故障时自动切换&#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;首先声明…

Spring Data访问Elasticsearch----路由值Routing values

Spring Data访问Elasticsearch----路由值Routing values 一、join-types的路由二、自定义路由值 当Elasticsearch将文档存储在具有多个分片的索引中时&#xff0c;它会根据文档的id确定要使用的分片。有时有必要预先定义多个文档应该在同一个shard上建立索引&#xff08;join-t…

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

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

LeetCode题练习与总结:组合总和Ⅱ

一、题目 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 二、解题思路 排序&#xff1a…

前端项目,个人笔记(二)【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;成…

拦截器(springboot)

1、拦截器介绍 在SpringBoot中&#xff0c;拦截器是一种用于拦截请求并在处理请求之前或之后执行特定操作的机制。 拦截器可以用于实现一些通用的功能&#xff0c;例如身份验证、日志记录、性能监控等。 Springboot中的拦截器是通过实现HandlerInterceptor接口来实现的&#x…

[Halcon学习笔记]机器视觉缺陷检测常用方法对比总结

1、介绍 缺陷检测时机器视觉需求中最复杂难度较大的一类需求。究其原因&#xff0c;主要是在项目开发过程中首先要保证检测的稳定性和精度&#xff0c;又要实现缺陷检测的通用性&#xff0c;常见的缺陷&#xff1a;凹凸、污点瑕疵、划痕、裂缝、伤痕、毛刺等等类型种类繁杂&am…

uniapp 使用sqlite时无法读取到db文件中的数据

问题 {“code”:-1404,“message”:“android.database.sqlite.SQLiteException: no such table: user (Sqlite code 1): , while compiling: select * from user, (OS error - 2:No such file or directory),http://ask.dcloud.net.cn/article/282”} at pages/index/index.vu…

Python内置对象

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

STP环路避免实验(思科)

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

【AI案例】做AI视频如何实现数字人实时口型同步

首先,这个方案提供了一个令人瞩目的实时唇语同步API。这一技术能够将任何视频与任何语言的音频进行视觉配音,而且无需繁琐的训练过程。这样的功能极大地拓宽了视频内容的传播范围,使得无论语言背景如何,人们都能够理解并享受视频内容。 其次,这个API的适用性非常广泛,无…

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(…

第十三届“中关村青联杯”全国研究生数学建模竞赛-A题:多无人机协同任务规划(续)

目录 7.2 模型三的建立与求解 8 问题四:针对远程雷达的分步优化模型 9 问题五:模型分析

【Pandas】(2)DataFrame

Pandas 的 DataFrame 是一个二维的、大小可变的、异质型表格数据结构,带有标签化的轴(行和列)。简单来说,你可以将 DataFrame 看作是一个 Excel 表格或 SQL 数据表,在数据分析和数据处理中非常有用。 创建 DataFrame DataFrame 可以通过多种方式创建,最常用的是直接从字…

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

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