黑马Spring学习笔记(一)——IOC/DI核心概念、入门案例

news2024/11/15 3:31:25

目录

一、Spring系统架构和学习路线

二、Spring核心概念

2.1  IOC、IOC容器、Bean、DI

2.1.1  IOC(Inversion of Control)控制反转

2.1.2  DI(Dependency Injection)依赖注入

2.2  核心概念小结

三、入门案例

3.1  IOC入门案例

3.2  DI入门案例

3.3  IOC相关内容——Bean

3.3.1  Bean的基础配置

3.3.2  Bean的实例化

3.4  DI相关内容——DI依赖注入

3.4.1  Setter注入

3.4.2  构造器注入(*)

3.4.3  自动配置(*)

3.4.4  集合注入


一、Spring系统架构和学习路线

        Spring Framework的5版本目前没有最新的架构图,而最新的是4版本,所以接下来主要研究的是4的架构图。

         学习路线:

二、Spring核心概念

使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象

2.1  IOCIOC容器、BeanDI

2.1.1  IOC(Inversion of Control)控制反转

  • 控制反转:使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部。
  • Spring 提供了一个容器,称为 IOC 容器 ,用来充当 IOC 思想中的 " 外部",IOC 思想中的 别人 [ 外部 ] 指的就是 Spring IOC 容器。
  • IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象,被创建或被管理的对象在 IOC 容器中统称为 Bean IOC 容器中放的就是一个个的 Bean 对象。
  • IOC 容器中创建好 service dao对象后,程序还不能正确执行,因为 service 运行需要依赖 dao对象,但是 service 对象和 dao对象没有任何关系,也就是说要绑定 service dao对象之间的关系,绑定关系就要用到 DI。

2.1.2  DI(Dependency Injection)依赖注入

  • 依赖注入:在容器中建立beanbean之间的依赖关系的整个过程,称为依赖注入(业务层要用数据层的类对象,以前是自己new的,现在自己不new了,靠别人[外部其实指的就是IOC容器]来给注入进来)

2.2  核心概念小结

介绍完Spring的IOCDI的概念后,我们会发现这两个概念的最终目标就是:充分解耦,具体实现靠:

  • 使用IOC容器管理beanIOC)
  • IOC容器内将有依赖关系的bean进行关系绑定(DI
  • 最终结果为:使用对象时不仅可以直接从IOC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

三、入门案例

3.1  IOC入门案例

***理解原理,实际开发不会用到!***

分析
(1)Spring 是使用容器来管理 bean 对象的,那么管什么 ?
主要管理项目中所使用到的类对象,比如(Service和Dao)
(2) 如何将被管理的对象告知 IOC 容器 ?
使用配置文件
(3) 被管理的对象交给 IOC 容器,要想从容器中获取对象,就先得思考如何获取到 IOC 容器 ?
Spring框架提供相应的接口
(4)IOC 容器得到后,如何从容器中获取 bean?
调用Spring框架提供对应接口中的方法
具体步骤
实现
步骤1:创建Maven项目

步骤2:添加Spring依赖的jar包

步骤3:添加案例中需要的

创建BookService,BookServiceImplBookDaoBookDaoImpl四个类

步骤4:添加spring配置文件

resources下添加spring配置文件applicationContext.xml,并完成bean的配置

步骤5:在配置文件中完成bean的配置

步骤6:获取IOC容器

 步骤7:从容器中获取对象进行方法调用

步骤8:运行程序

3.2  DI入门案例

***理解原理,实际开发不会用到!***

分析
  • 要想实现依赖注入,必须要基于IOC管理Bean
  • Service中使用new形式创建的Dao对象需要删除掉,最终要使用IOC容器中的bean对象
  • Service 中需要的 Dao 对象如何进入到 Service 中?
    Service中提供方法,让SpringIOC容器可以通过该方法传入bean对象
  • Service Dao 间的关系如何描述?
    使用配置文件
具体步骤
实现
步骤 1: 去除代码中的 new
BookServiceImpl 类中,删除业务层中使用 new 的方式创建的 dao 对象

步骤 2: 为属性提供 setter 方法
BookServiceImpl 类中 , BookDao 提供 setter 方法

步骤 3: 修改配置完成注入

 注意:两个bookDao含义不同,差别如图:

步骤 4: 运行程序

3.3  IOC相关内容——Bean

***理解原理,实际开发不会用到配置文件,更多使用注解开发!***

3.3.1  Bean的基础配置

Bean的idclass属性

<bean id="" class=""/>

id: bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一

class: bean的类型,即配置的bean的全路径类名

Bean的name属性

定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔,例如:

<bean id="bookService" name="service service4 bookEbi"
class="com.itheima.service.impl.BookServiceImpl">

Bean的scope配置

(1)单例(默认)——singleton

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="singleton"/>

单例的意思就是,同一个bean获取两次,将对象打印到控制台,打印出的地址值完全一致。 

默认bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高。

(2)非单例——prototype

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>

总结

哪些 bean 对象适合交给容器进行管理(即单例) ?
  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象
哪些 bean 对象不适合交给容器进行管理(即非单例) ?
  • 封装实例的域对象,因为会引发线程安全问题,所以不适合

3.3.2  Bean的实例化

第一种:构造方法实例化(常用)

结论:Spring底层使用的是类的无参构造方法,并且能访问到类中的私有构造方法,显而易见,Spring底层用的是反射

第二种:静态工厂实例化(*)

第三种:FactoryBean(实用)

  1. 准备一个 UserDao 和UserDaoImpl类

      

  2. 创建一个 UserDaoFactoryBean 的类,实现FactoryBean接口,重写接口的方法
  3. Spring 的配置文件中进行配置
    <bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
  4. 创建一个运行类AppForInstanceUser
  5. 运行
         注意:该方法设置的对象默认也为单例,单例/非单例的具体实现如下:
                   在UserFactoryBean类中实现接口中的方法isSingleton():
public boolean isSingleton() {
    return false;
}

3.4  DI相关内容——DI依赖注入

***理解原理,实际开发使用的是注解开发!***

3.4.1  Setter注入

  • 对于引用数据类型使用的是<property name=" " ref=" "/>
  • 对于简单数据类型使用的是<property name=" " value=" "/>

(1)引用类型注入

        上面的例子就是引用类型注入,例如现在有BookDao,UserDao接口(不再赘述),有BookServiceImpl实现类,代码如下:

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

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

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

        现在,我们在配置文件中使用property标签注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
    <property name="userDao" ref="userDao"/>
</bean>

(2)简单类型注入

BookDaoImpl实现类如下:

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;

    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public void save() {
        System.out.println("book dao save
..."+databaseName+", "+connectionNum);
    }
}

        现在,我们在配置文件中使用property标签注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <property name="databaseName" value="mysql"/>
    <property name="connectionNum" value="10"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
    <property name="userDao" ref="userDao"/>
</bean>

3.4.2  构造器注入(*)

  • 引用数据类型 <constructor-arg name="" index="" type="" ref=""/>
  • 简单数据类型 <constructor-arg name="" index="" type="" value=""/>

        实际开发中,更推荐使用Setter注入,故构造器注入

3.4.3  自动配置(*)

方式:

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用自动装配

3.4.4  集合注入

在BookDaoImpl实现类中,不再是引用类型和简单数据类型,而是集合类型,常见的集合类型有:

  • 数组
  • List
  • Set
  • Map
  • Properties

在配置文件中,注入数组数据类型如下:

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

其他略



笔记跟课:

https://www.bilibili.com/video/BV1Fi4y1S7ix/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click&vd_source=0e0517ebadf244dd640ab0b61dd700c5https://www.bilibili.com/video/BV1Fi4y1S7ix/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click&vd_source=0e0517ebadf244dd640ab0b61dd700c5



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

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

相关文章

【C++入门】引用、内联函数、auto关键字、基于范围的for循环(C++11)、指针空值nullptr(C++11)

文章目录引用引用概念引用特性引用使用场景常引用内联函数宏的优缺点&#xff1f;C有哪些技术替代宏&#xff1f;auto关键字auto不能推导的场景基于范围的for循环(C11)指针空值nullptr(C11)引用 引用概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&…

一篇搞懂UnitTest

unittest单元测试框架是受到 JUnit 的启发&#xff0c;与其他语言中的主流单元测试框架有着相似的风格。其支持测试自动化、支持将测试样例聚合到测试集中&#xff0c;并将测试与报告框架独立开来。unittest模块是Python标准库中的模块。在此之前需要先了解几个概念&#xff1a…

linux高级命令之线程执行带有参数的任务

线程执行带有参数的任务学习目标能够写出线程执行带有参数的任务1. 线程执行带有参数的任务的介绍前面我们使用线程执行的任务是没有参数的&#xff0c;假如我们使用线程执行的任务带有参数&#xff0c;如何给函数传参呢?Thread类执行任务并给任务传参数有两种方式:args 表示以…

NTC热敏电阻

NTC热敏电阻&#xff1a; 负温度系数热敏电阻。 Negative Temperature Coefficient Thermistor 特性&#xff1a; 由锰 (Mn) 、镍 (Ni) 、钴 (Co) 等成分的氧化物烧制而成的陶瓷。阻值随温度上升而下降。 工作温度范围宽&#xff1a;一般的都可用于-40℃ to 125℃。有的高…

[Pytorch] Linear层输出nan

参考链接&#xff1a; https://discuss.pytorch.org/t/well-formed-input-into-a-simple-linear-layer-output-nan/74720/11 总结原因&#xff1a; numpy需要更新 PS. 查看numpy版本号 打开Anaconda Prompt 进入环境 输入命令conda activate envname 然后输入pip show numpy…

MongoDB 自动增长

MongoDB 自动增长 MongoDB 没有像 SQL 一样有自动增长的功能&#xff0c; MongoDB 的 _id 是系统自动生成的12字节唯一标识。但在某些情况下&#xff0c;可能需要实现 ObjectId 自动增长功能。而MongoDB 并没有提供这个功能&#xff0c;那么可以通过编程的方式来实现_id字段自…

Qt音视频开发14-音视频文件保存基类的设计

一、前言 视频综合应用示例&#xff0c;包括了多种内核&#xff0c;在保存文件这个功能上&#xff0c;需要一个通用的文件保存基类AbstractSaveThread&#xff0c;这个基类定义了是否打印线程消息标志位、直接写入还是排队写入标志位、文件生成后是否调用转换合并标志位、是否…

Linux下的Jenkins安装教程

当前环境 CentOS 7.8Java 11&#xff08;注意当前jenkins支持的Java版本最低为Java11&#xff09;FinalShell 3.9&#xff08;操作环境&#xff09; 安装Jenkins PS&#xff1a;不建议使用Docker安装Jenkins&#xff0c;因为使用Jenkins的时候一般会调用外部程序&#xff0c;…

【猜名次】-C语言-题解

1. 描述&#xff1a; 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果&#xff1a; A选手说&#xff1a;B第二&#xff0c;我第三&#xff1b; B选手说&#xff1a;我第二&#xff0c;E第四&#xff1b; C选手说&#xff1a;我第一&#xff0c;D第二&#x…

【工作10年+的大厂资深架构师万字长文总结 精华收藏!】怎样设计高可用、高性能系统?关于高可用高性能系统架构和设计理论和经验总结...

本文从研发规范层面、应用服务层面、存储层面、产品层面、运维部署层面、异常应急层面这六大层面去剖析一个高可用的系统需要有哪些关键的设计和考虑.O、前言随着业务在线化互联网化的高速发展&#xff0c;企业对核心业务系统的稳定性、可靠性、有效性、业务连续性等有了更高的…

openpnp - 普通航空插头和PCB的连接要使用线对板连接器

文章目录openpnp - 普通航空插头和PCB的连接要使用线对板连接器概述改进实际效果总结ENDopenpnp - 普通航空插头和PCB的连接要使用线对板连接器 概述 和同学讨论问题, 准备将航空插头连接到PCB上. 航空插头选用GX12-4公头, 拧到开孔的铁板上. 然后航空插头公头再与PCB连接. 铁…

【数据库】HNU数据库系统期末考试复习重点

前言 今天刚结束考试&#xff0c;考的范围基本没有超过这套重点内容&#xff0c;觉得整理的这份资料还算比较有用&#xff0c;遂睡前整理了下分享给大家&#xff0c;希望能帮到要准备数据库期末又时间紧张的学弟学妹~ 文章参考&#xff1a; 1.课程老师发《数据库期末考试复习…

【项目精选】基于网络爬虫技术的网络新闻分析(论文+源码+视频)

基于网络爬虫技术的网络新闻分析主要用于网络数据爬取。本系统结构如下&#xff1a; &#xff08;1&#xff09;网络爬虫模块。 &#xff08;2&#xff09;中文分词模块。 &#xff08;3&#xff09;中3文相似度判定模块。 &#xff08;4&#xff09;数据结构化存储模块。 &…

120个IT冷知识,看完就不愁做选择题了

目录 IT冷知识 01-10 1.冰淇淋馅料 2.蠕虫起源 3.Linux和红帽子 4."间谍软件"诞生 5.游戏主机的灵魂 6.Linux之父 7.NetBSD的口号 8.安卓起源 9.不是第七代的 Win 7 10.域名金字塔 11~20 11.神奇魔盒 12. 第一个Ubuntu 正式版本 13.巾帼英雄 14.密码…

【高可用系统架构设计】SLA服务可用性4个9是什么意思?如何保证服务的高可用性 HA(High Availability)?...

如何保证服务的高可用性 HA&#xff08;High Availability&#xff09;?高可用HA&#xff08;High Availability&#xff09;是分布式系统架构设计中必须考虑的因素之一&#xff0c;它通常是指&#xff0c;通过设计减少系统不能提供服务的时间。方法论上&#xff0c;高可用是通…

springboot整合阿里云oss文件服务器

springboot整合阿里云oss文件服务器一、申请Bucket二、 获取AccessKey ID、AccessKey Secret三、 springboot整合3.1 在application.yml 配置参数3.2 oss需要的pom3.3 配置 oss配置类3.4 oss的controller类3.5 oss的service类以及impl一、申请Bucket 进入该网址对象存储oss述 …

18 二叉树

文章目录1 为什么需要树这种数据结构2 树示意图3 二叉树的概念4 二叉树的遍历5 二叉树的遍历的代码实现6 二叉树的遍历查找的代码实现1 为什么需要树这种数据结构 1) 数组存储方式的分析 优点&#xff1a;通过下标方式访问元素&#xff0c;速度快。对于有序数组&#xff0c;还…

【Linux】进程状态

文章目录1. 阻塞1. 举例2. 为什么要阻塞&#xff1f;3.操作系统层面上如何理解进程等待某种资源就绪呢&#xff1f;资源进程4. 总结2.挂起3.Linux进程状态1. R状态进程只要是R状态&#xff0c;就一定是在CPU运行吗&#xff1f;证明当前进程运行状态生成程序查看进程2. S休眠状态…

New和Malloc的使用及其差异

1&#xff0c;new的使用关于new的定义&#xff1a;new其实就是告诉计算机开辟一段新的空间&#xff0c;但是和一般的声明不同的是&#xff0c;new开辟的空间在堆上&#xff0c;而一般声明的变量存放在栈上。通常来说&#xff0c;当在局部函数中new出一段新的空间&#xff0c;该…

Go项目(三)

文章目录用户微服务表结构查表web 服务跨域问题图形验证码短信用户注册服务中心注册 grpc 服务动态获取端口负载均衡配置中心启动项目小结用户微服务 作为系统的第一个微服务&#xff0c;开发的技术点前面已经了解了一遍&#xff0c;虽有待补充&#xff0c;但急需实战这里主要…