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

news2024/11/24 7:50:18

在这里插入图片描述

这里写目录标题

  • 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>

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

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

相关文章

Python基础:输入输出详解-输出字符串格式化

Python中的输入和输出是编程中非常重要的方面。 1. 输入输出简单介绍 1.1 输入方式 Python中的输入可以通过input()函数从键盘键入&#xff0c;也可以通过命令行参数或读取文件的方式获得数据来源。 1&#xff09;input()示例 基本的input()函数&#xff0c;会将用户在终端&…

力扣栈与队列--总结篇

前言 八道题&#xff0c;没想到用了五天。当然需要时间的沉淀&#xff0c;但是一天不能啥也不干啊&#xff01; 内容 首先得熟悉特点和基本操作。 栈与队列在计算机底层中非常重要&#xff0c;这就是为什么要学好数据结构。 可视化的软件例如APP、网站之类的&#xff0c;都…

Kotlin原理+协程基本使用

协程概念 协程是Coroutine的中文简称&#xff0c;co表示协同、协作&#xff0c;routine表示程序。协程可以理解为多个互相协作的程序。协程是轻量级的线程&#xff0c;它的轻量体现在启动和切换&#xff0c;协程的启动不需要申请额外的堆栈空间&#xff1b;协程的切换发生在用…

AVL树的底层实现

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

腾讯云服务器便宜吗?腾讯云服务器怎么买便宜?附优惠链接

首先&#xff0c;咱们来看一下大家最关心的一个问题&#xff1a;“腾讯云服务器便宜吗&#xff1f;”我的答案是&#xff1a;“YES&#xff01;它真的很便宜&#xff01;”比如&#xff0c;轻量2核2G3M服务器&#xff0c;1年只需要88元&#xff0c;是不是很划算&#xff1f;再比…

实例解释遇到前端报错时如何排查问题

前端页面报错&#xff1a; 1、页面报错500&#xff0c;首先我们可以知道是服务端的问题&#xff0c;需要去看下服务端的报错信息&#xff1a; 2、首先我们查看下前端是否给后端传了id: 我们可以看到接口是把ID返回了&#xff0c;就需要再看下p_id是什么情况了。 3、我们再次请…

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

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

双11背后的中国云厂商:新“标准化”,和调整后的新韧性

降价并不代表一味的压缩自身利润空间&#xff0c;云厂商已经开始向具有更高利润空间的PaaS、SaaS产品腾挪&#xff0c;核心产品在总包占比越来越高。 作者|斗斗 编辑|皮爷 出品|产业家 今年云厂商&#xff0c;全面拥抱双11。 作为中国最大的云计算服务提供商&#xff0…

关于苏州立讯公司国产替代案例(使用我公司H82409S网络变压器和E1152E01A-YG网口连接器产品)

关于苏州立讯公司国产替代案例&#xff08;使用我们公司的H82409S网络变压器和E1152E01A-YG网口连接器产品&#xff09; 苏州立讯公司是一家专注于通信设备制造的企业&#xff0c;他们在其产品中选择了我们公司的H82409S网络变压器和E1152E01A-YG网口连接器&#xff0c;以实现…

在线协作工具都有哪些?推荐这10款

如今&#xff0c;互联网的快速发展不仅改变了我们的生活方式&#xff0c;也改变了我们的工作方式。 特别是对于一些与产品设计相关的公司或团体&#xff0c;网络不仅为其设计提供了稳定的资源和灵感&#xff0c;而且为成员之间的沟通和合作提供了更大的便利。 如果您也需要为…

ke11介绍本地,会话存储

代码顺序: 1.设置input,捕获input如果有多个用属性选择符例如 input[typefile]点击事件.向我们的本地存储设置键值对 2.在点击事件外面设置本地存储表示初始化的值.点击上面的事件才能修改我们想修改的值 会话(session)浏览a数据可以写到本地硬盘,关闭页面数据就没了 本地(…

JPA整合Sqlite解决Dialect报错问题, 最新版Hibernate6

前言 我个人项目中&#xff0c;不想使用太重的数据库&#xff0c;而内嵌数据库中SQLite又是最受欢迎的&#xff0c; 因此决定采用这个数据库。 可是JPA并不支持Sqlite&#xff0c;这篇文章就是记录如何解决这个问题的。 原因 JPA屏蔽了底层的各个数据库差异&#xff0c; 但是…

使用Python的time库来格式化时间

目录 一、引言 二、time库简介 三、使用time库来格式化时间 四、使用time库进行时间戳转换 五、使用time库获取当前时间 六、使用time库进行延时操作 七、使用time库计算时间差 八、使用time库获取系统时间 九、使用time库的其他功能 总结 一、引言 在Python中&…

鸿蒙OS应用开发初体验

什么是HarmonyOS&#xff1f; HarmonyOS&#xff08;鸿蒙操作系统&#xff09;是华为公司开发的一款基于微内核的分布式操作系统。它是一个面向物联网&#xff08;IoT&#xff09;时代的全场景操作系统&#xff0c;旨在为各种类型的设备提供统一的操作系统平台和开发框架。Har…

自媒体剪辑必备,6个音效素材网站,你值得拥有。

这6个剪辑必备的音效素材网站一定要收藏好了&#xff0c;有了这几个网站能让你在剪辑的时候事半功倍&#xff0c;还不用担心版权问题。话不多说&#xff0c;直接上干货。 1、菜鸟图库 https://www.sucai999.com/audio.html?vNTYwNDUx 菜鸟图库是一个综合性素材网站&#xff…

ref属性

Vue 中 可以给标签&#xff08;HTML元素标签、组件标签&#xff09;加上一个 ref 属性&#xff0c;作用就是给 标签加上一个标识&#xff0c;可以通过该标识获取当前需要的DOM元素或者组件实例对象。 通过原生js获取DOM 如果使用原生js来获取DOM元素时&#xff0c;我们最简单的…

Kafka学习笔记(一)

目录 第1章 Kafka概述1.1 消息队列&#xff08;Message Queue&#xff09;1.1.1 传统消息队列的应用场景1.1.2 消息队列的两种模式 1.2 定义 第2章 Kafka快速入门2.1 安装部署2.1.1 集群规划2.1.2 jar包下载2.1.3 集群部署 2.2 Kafka命令行操作 第3章 Kafka架构深入3.1 Kafka工…

23111708[含文档+PPT+源码等]计算机毕业设计基于javaweb的旅游网站前台与后台旅景点

文章目录 **论文截图&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 下面是系统运行起来后的部分截图&#xff1a; 论文截图&#xff1a; 实现&#xff1a; 代码片段&#xf…

身份证如何加水印?一分钟解决!

身份证是对我们每个人来说都非常重要的东西&#xff0c;在身份证上添加水印&#xff0c;可以明确证件的所有权和合法性&#xff0c;可以在一定程度上防止身份证被用于非法目的&#xff0c;如身份盗用、欺诈等。下面就向大家介绍三种实用的方法和具体操作步骤。 方法一&#xff…

剑指Offer || 116.省份数量

题目 有 n 个城市&#xff0c;其中一些彼此相连&#xff0c;另一些没有相连。如果城市 a 与城市 b 直接相连&#xff0c;且城市 b 与城市 c 直接相连&#xff0c;那么城市 a 与城市 c 间接相连。 省份 是一组直接或间接相连的城市&#xff0c;组内不含其他没有相连的城市。 …