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;
    @Override
    public 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;
    @Override
    public 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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://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">

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

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

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

相关文章

3.19作业

1、思维导图 2、模拟面试题 1&#xff09;TCP通信中的三次握手和四次挥手 答&#xff1a;三次握手 客户端向服务器发送连接请求 服务器向客户端回复应答并向客户端发送连接请求 客户端回复服务端&#xff0c;并建立联系 四次挥手 进程a向进程b发送断开连接请求…

单例设计模式,各种排序复习

1.单例设计模式 资料来源 1.1单例模式是什么&#xff1f; 单例模式&#xff0c;属于创建类型的一种常用的软件设计模式。 通过单例模式的方法创建的类在当前进程中只有一个实例&#xff08;根据需要&#xff0c;也有可能一个线程中属于单例&#xff0c;如&#xff1a;仅线程…

qt Qt Remote Object(QtRO)实现进程间通信

简介 Qt Remote Object简称QtRO&#xff0c;这是Qt5.9以后官方推出来的新模块&#xff0c;专门用于进程间通信&#xff08;IPC&#xff09;。是基于Socket来封装的&#xff0c;兼容LPC和RPC。LPC即Local Process Communication&#xff0c;而RPC是指Remote Process Communicat…

瑞士百达资产管理有限公司拟增三大去中心化数字加密货币支付接口!

简介: 瑞士百达集团成立于1805年,欧洲第三大财富管理公司, 集团拥有约 5,300 名员工,其中包括 900 名投资经理。它在金融服务中心拥有 30 个办事处网络,包括在日内瓦、卢森堡、拿骚、香港和新加坡的注册银行,百达集团管理的资产总额达6380亿瑞士法郎(7670亿美元)。 瑞士百达资…

触手可及的社交:揭示Facebook如何让每个人都能参与其中

引言 在当今社会&#xff0c;Facebook已经成为了人们日常生活中不可或缺的一部分。无论是与朋友、家人保持联系&#xff0c;还是参与社群讨论、获取新闻信息&#xff0c;Facebook都提供了一个触手可及的社交平台。本文将探讨Facebook如何让每个人都能轻松参与其中&#xff0c;…

ClickHouse01-什么是ClickHouse

什么是ClickHouse&#xff1f; 关于发展历史存在的优势与劣势什么是它风靡的原因&#xff1f; 什么是ClickHouse&#xff1f; 官方给出的回答是&#xff0c;它是一个高性能、列式存储、基于SQL、供在线分析处理的数据库管理系统 当然这边不得不提到OLAP(Online Analytical Pr…

代码随想录day24(1)二叉树:最大二叉树(leetcode654)

题目要求&#xff1a; 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大二叉树。 通过给定的数组构…

【C++】AVL树的两单旋和两双旋

目录 1. 新节点插入较高左子树的左侧---左左&#xff1a;右单旋 代码 2. 新节点插入较高右子树的右侧---右右&#xff1a;左单旋 代码 3. 新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋 ​编辑 代码 4. 新节点插入较高右子树的左侧---右左&#xff1a;先…

如何选择适合大功率直流电子负载

选择适合大功率直流电子负载时&#xff0c;需要考虑以下几个关键因素&#xff1a; 功率范围&#xff1a;首先&#xff0c;需要确定所需的最大功率范围。大功率直流电子负载通常有不同的功率等级&#xff0c;如1kW、2kW、5kW等。根据实际应用场景和需求&#xff0c;选择合适的功…

CTF题型 php反序列化进阶(1) php原生类 例题和总结

CTF题型 php反序列化进阶(1) php原生文件操作类 例题和总结 文章目录 CTF题型 php反序列化进阶(1) php原生文件操作类 例题和总结特征原理 我们可以通过PHP自身本来就有的类来进行文件操作扫描目录的三个类DirectoryIterator(支持glob://协议)FilesystemIterator&#xff08;继…

基于springboot的stone音乐播放器的设计与实现

摘 要 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;stone音乐播放器展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;…

使用 CSS 实现毛玻璃效果

在现代 Web 设计中,毛玻璃效果越来越受欢迎。它能够让界面元素看起来更加柔和、朦胧,同时又不会完全遮挡背景内容,给人一种透明而又不失质感的视觉体验。虽然过去实现这种效果需要借助图像编辑软件,但现在只需要几行 CSS 代码,就可以在网页上呈现出令人惊艳的毛玻璃效果。 使用…

小火星露谷管理器 报错:“你似乎没有安装Edge的webview2”

错误 解决办法 你可以到这个地方下载安装webview2 https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/?formMT00IS

如何进行汇川PLCH1U-XP系列PLC远程监控?

在工业自动化的浪潮中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;作为控制系统的核心&#xff0c;其稳定性和可靠性对于生产流程的顺畅运行至关重要。汇川PLCH1U-XP系列以其高性能和广泛的应用场景&#xff0c;在工业控制领域占有一席之地。然而&#xff0c;对于…

华为机试真题练习汇总(81~90)

华为机试真题练习汇总&#xff08;81~90&#xff09; 华为机试真题练习汇总&#xff08;81~90&#xff09;HJ81 字符串字符匹配** HJ82 将真分数分解为埃及分数HJ83 二维数组操作HJ84 统计大写字母个数HJ85 最长回文子串HJ86 求最大连续bit数HJ87 密码强度等级* HJ88 扑克牌大小…

2024年 嵌入式系统设计师(中级)

2024年 嵌入式系统设计师全套视频、历年真题及解析、历年真题视频解析、教材、模拟题、重点笔记等资料 1、2023、2022、2021、2020年全套教程精讲视频。 2、嵌入式系统设计师历年真题及解析&#xff08;综合知识、案例分析&#xff09;、历年真题视频解析。 3、官方最新信息嵌…

【爬虫实战】使用Python获取花粉俱乐部中Mate60系列的用户发帖数据

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

每日一题 1969 数组元素的最小非零乘积

1969. 数组元素的最小非零乘积 题目描述&#xff1a; 给你一个正整数 p 。你有一个下标从 1 开始的数组 nums &#xff0c;这个数组包含范围 [1, 2p - 1] 内所有整数的二进制形式&#xff08;两端都 包含&#xff09;。你可以进行以下操作 任意 次&#xff1a; 从 nums 中选…

yolov7 gui 轻松通过GUI来实现车辆行人计数

YOLOv7 GUI 是一款用户友好型图形界面应用程序&#xff0c;专为简化基于YOLOv7&#xff08;You Only Look Once version 7&#xff09;的目标检测流程而设计。该工具允许用户无需深入掌握命令行操作和复杂编程细节&#xff0c;即可方便快捷地运行YOLOv7模型来检测图像或视频中的…

进制,码制及其表示范围

一 进制 1 常见的进制及其简写 十进制&#xff08;Dec&#xff09;二进制&#xff08;Binary&#xff09;十六进制&#xff08;Hex&#xff09;八进制&#xff08;Octal&#xff09; 2 进制之间的相互转换 二 码制 1 常用的码制 三 各码制在定点整数时表示的范围 个人推导…