控制反转|学习笔记

简介: 快速学习控制反转

开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术控制反转学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/80/detail/15902


控制反转


内容介绍:

一、控制反转

二、spring 容器自动装配例子

 

一、控制反转

1、控制反转是 spring 容器的一个重要特征,控制反转是指在spring容器中间 Bean 对自己的依赖是不需要自己管理的,可以通过配置信息告诉spring之间的依赖是什么,但很多时候 spring 容器是可以基于某一种规则自动的管理spring中间的所 Bean 对象之间的赖。Spring 容器怎样负责管理 Bean 对象的依赖?

它采用依赖注入(DI)的方式来实现控制反转,需要通过注解的方式告诉spring容器 Bean 对象之间是会相互关联的,最常用的一个注解是@Autowired,在 Bean 对象的属性或 Bean 对象的方法前面用 Autowired 注解告诉 spring容器这样一个属性,或者在方法里的参数是需要由spring容器来注入对象的。

2、默认匹配规则

Spring容器首先会查询对应的类型是相同的 Bean 对象,如果同一个类型的 Bean 对象只有一个,那他就会把这个 Bean 对象装配给属性或者装配给方法的参数。如果 Autowired 所绑定的数据类型得到的结果不是一个的话,Autowired 会根据变量的名称来查找,也就是我们绑定的属性名称,或方法中间参数的名称,跟 Bean 对象的ID是一样的,就会把它对上来。

 

二、spring容器自动装配例子

1、通过代码看 Autowired 是怎样使用的?下面是spring容器自动装配的例子,在这个例子中间做了三个让它自动装配的类,分别是 Boss、Car、Office,把 Car 和 Office 装到 Boss 里去,装配的方式可以有多种,可以把它写在属性前面或构造函数前面,也可以写在 setter 方法前面,所以 Boss 做了三个类,分别对应三种不同的 Bean 对象把它装配上来的方式,而 Car 的对象和 Office 对象做了一些特别的处理,对于 Office 对象来说比较简单,它是一个普通的对象;但是 Car 做了一个

口,在 Car 底下做了两个实例类,分别是 Toyota 和 Haval。

做着两个实例类的目的是想看一下在自动装配的时候,如果在 Car 里有两个实例的

话,它是怎样来装配的?通过ID来确认最后装配的是哪一个对象?

下面来看一下代码,自动装配例子在第一章的 Spring From Work 里面的autowireddemo 工程下,在这个工程底下建了几个 Bean。第一个非常简单的

Bean 叫 Office,用注解来表现它,这个 Bean 里面没有任何实现。

第二个建了一个接口叫 Car,这个接口前面没有任何注解,

2、有两个对象来实现 Car 的接口,分别是 Toyota 和 Haval,这个 component 里没写任何内容,因为只想看一下它自动绑定的过程,实现了 Car 的接口

publicclassToyotaimplementsCar{

另外一个是Haval,实现了 Car 的接口。

public class Haval implements Car {

需要把 Car 和 Office 注入到 Boss 里,Boss 写了三个类,分别用来演示三种不同的注入方式,第一个是 Boss_constructor,因为想通过它的构造函数进来,在这个例子中首先用的是 car 类型。

@Component

public class Boss_constructor{

private car car;

private office office;

@Autowired

public Boss_constructor(Car carOffice office){

this.car = car;

this.office = office;

构造函数中间有两个参数,一个是car,一个是office。在这个构造函数中间,如果是ncanr类型的话,在代码中间是会出问题的,因为跑起来的时候 Bean 不知道是要把 Toyota 注入进去,还是把 Haval 注入进去,先跑一下这段代码,看看它的问题在什么地方?跑起来之后发现它会报错,报的错是application where to start 起不来

image.png

起不来的原因是因为partment零的 boss_constructor 第一个参数需要一个 Bean 对象,但是在spring容器中间按照配置信息只能找到两个,分别是 Toyota 和 Haval,这样就没办法把它绑定上去。

3我们可以把代码运维改一下,不改它的的类型,把变量名称改成 Toyota,这里面所有的 Bean 对象都没有定义 id,所以他的ID是类名的首字母小写,Toyota 类型的 Bean 对象ID是 Toyota,改完之后再 spring-bootrun 跑一下,这个时候就没有

问题了。

image.png

其他的也类似,下面看一下通过 property 来注进去的

@Component

public class boss_property {

@Autowiret

private Car haval:

@Autowire

private office office;

property 不需要写构造函数前,不需要写在方法前面,直接写在属性前面,这样当他实例化出来的时候会根据类型找对应的,这个例子中间 car 注册的不是 Toyota注册Haval,这样跑起来就不会出错。

4、第三个是通过setter函数

@Component

public class Boss_Setter {

private Car car;

private Office office;

@Autowired

public void setCar(car toyota){

this.car = toyota;

@Autowired

public void setOffice(Office office) { this.office = office; }

setter函数是注册 Toyota,虽然它是 car 的类型,但是在 setter 函数的参数上面它的名字叫做 toyota,这样就会用 ID 找 car 类型下的 ID 叫做 Toyota 的 Bean 对象把它注册进来,这是自动装配的一个过程。现在已经没有错了,但是跑起来以后,怎样知道自动装配是否正确?利用了在下一章要讲的  Aprit 接口,通过一个界面的工程叫做 Admits UI,这次只是看它的结果,把界面的工程跑起来,界面的工程在配置文件中定义了端口在8081,因为 autowired 端口放在8080,把 autowired 工程也跑起来,跑在8080。两个工程都跑起来以后,就可以看8081端口上 Spring Boot Admin 工具,这个工具能看到在服务器集群中间到底跑了多少 Spring Boot

的 Application?现在只有一个,

image.png

要看的是这个 Bean 对象,利用application接口可以看到 Bean 对象的一些配置,到 wallboard 里看 Application 的配置是什么?

image.png

关心的是这里面绑定了多少 Bean ,这里面有内部的 Bean ,也有我们定义的。

首先看到的是 boss_Setter  Bean,boss_Setter  Bean 绑上的是 Toyota,虽然 Bean 中间定义的类型是接口类型,但是因为用ID找到了toyoty对象,constructor 绑上的也是 Toyota,boss_property 绑上的是 Haval,这样就能看到绑定上去的东西都是不同类型的对象,根据ID找上去的。

image.png

相关文章
|
编解码 缓存 安全
用指纹浏览器为什么要搭配代理IP
指纹浏览器结合代理IP能有效提升网络隐私与安全。指纹浏览器通过生成独特用户标识防止追踪,但高级追踪技术仍可能暴露信息。代理IP可隐藏真实IP,增加匿名性,规避网络限制,并在指纹检测中混淆身份,增强安全。代理IP还能加速网络访问并提高稳定性。然而,选择可靠代理IP服务并遵守法规至关重要。
|
算法 计算机视觉 开发者
|
算法 安全 C语言
使用C语言实现DES算法代码
使用C语言实现DES算法代码
457 0
|
JavaScript 前端开发 Java
掌握 JavaScript:从初学者到高级开发者的完整指南(一)
掌握 JavaScript:从初学者到高级开发者的完整指南(一)
|
Shell Linux 调度
cgroup 资源控制介绍
cgroup 资源控制介绍
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
233 5
【数据结构】优先级队列(堆)从实现到应用详解
|
12月前
|
SQL 关系型数据库 MySQL
详解 pypika 模块:SQL 语句生成器,让你再也不用为拼接 SQL 语句而发愁
详解 pypika 模块:SQL 语句生成器,让你再也不用为拼接 SQL 语句而发愁
713 4
|
网络协议 C语言
C语言 网络编程(十)TCP通信创建流程---客户端
在TCP通信中,客户端需通过一系列步骤与服务器建立连接并进行数据传输。首先使用 `socket()` 函数创建一个流式套接字,然后通过 `connect()` 函数连接服务器。连接成功后,可以使用 `send()` 和 `recv()` 函数进行数据发送和接收。最后展示了一个完整的客户端示例代码,实现了与服务器的通信过程。
|
12月前
|
存储 算法 决策智能
【算法】博弈论(C/C++)
【算法】博弈论(C/C++)
|
存储 搜索推荐 算法
分享一个在线二维码生成器(基于qrcode.js开发)
一种二维码扫描与生成的工具, 它可生成个性化二维码, 支持文本、网址、图片、短信、电话等格式及主题,提供融合码功能
325 1