Spring05 SpringIOC DI

名词解释

今天我们来介绍Spring框架的最重要的part之一   SpringIOC 和 DI

这里的SpringIOC 其实是容器的意思,Spring是一个包含了很多工具方法的IOC容器

什么是IOC呢?

IOC其实是Spring的核心思想 

Inversion of Control  (控制反转)

可能这里你还是不理解这个是啥意思  其实就是我们一般创建对象的方式是使用new等方式创建,但是这里我们让Spring帮助我们创建对象,程序中只需要进行DI(对象注入)即可

Spring是一个IOC容器,所以有时候Spring也称之为Spring容器

这里举一个生活上的例子来解释一下SpringIOC的含义

我们招聘的时候,其实企业员工的入职和解雇等操作都得老板自己来,但是这里我们老板转给了HR来处理

案例对比

传统方式

假如我们需要实现这么一个依赖关系的思路

我们第一版本先使用传统方式进行操作一下

//轮胎
public class Tire {private int size;private String color;public Tire(int size) {System.out.println("tire size:"+size);}
}//底盘
public class Bottom {private Tire tire;public Bottom(int size) {tire = new Tire(size);System.out.println("tire init...");}
}//框架
public class Framework {private Bottom bottom;public Framework(int size) {bottom =  new Bottom(size);System.out.println("bottom init....");}
}//汽车
public class Car {private Framework framework;public Car(int size) {framework = new Framework(size);System.out.println("framework init...");}public void run() {System.out.println("car run...");}
}//启动类
public class Main {public static void main(String[] args){Car car = new Car(10);car.run();}
}

这里我们发现,我们如果对车万一需要进行一些操作,就会导致牵一发而动全身的效果

比如,如果我们为车的轮胎指定轮胎的厂家,这样我们就需要从轮胎类逐个的向上进行修改

这样程序的耦合度就太高了,于是我们现在介绍一下SpringIOC的方式来管理对象

注:这里只是模拟SpringIOC的方式来创建对象,这里SpringIOC其实我们也可以理解为一种思想,本质上要求交给Spring管理的对象是无状态的

SpringIOC版本

这里我们可以将对象的创建放到一块儿,Spring框架的想法是将对象的创建交给Spring来,我们向使用的时候只需要使用DI注入即可

这里我们先模拟一下程序的解耦,避免这种牵一发而动全身的操作存在

//bottom
public class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;System.out.println("tire init...");}
}//Car
public class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("framework init...");}public void run() {System.out.println("car run...");}
}//Framework
public class Framework {private Bottom bottom;public Framework(Bottom bottom) {this.bottom = bottom;System.out.println("bottom init....");}
}//Tire
public class Tire {private int size;private String color;public Tire(int size, String color) {System.out.println("tire size:"+size+",color:"+color);}
}//Main
public class Main {public static void main(String[] args) {Tire tire = new Tire(17, "red");Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}
}

这里我们发现了对象创建的思路是这样的

传统方式是创建Car再去找需求的依赖,是一个从下到上的结构

而IOC的方式是将对象依赖注入,是改进之后的控制权反转

这里我们可以看出IOC思维的优势

1.减少了类之间的耦合度

2.便于对象的集中管理

DI

解释就是依赖注入的意思,我们刚刚这种传对象的操作其实理论依据就是DI

IOC详解

下面我们进行SpringIOC的详解

首先我们提出一个Bean的概念 Spring中的对象称之为Bean

我们如果想把某些对象交给Spring管理,我们可以用以下注解来修饰

1.类注解

@Repository   @Service @Component  @Configuration   @Controller

2.方法注解

@Bean

注:Spring也不一定需要在web网页上显示,我们也可以在控制台打印

首先我们来尝试一下这五大类注解

@Component
public class UserComponent {public void doComponent(){System.out.println("UserComponent");}
}@Configuration
public class UserConfig {public void doConfig(){System.out.println("UserConfig doConfig");}
}@Repository
public class UserRepo {public void doRepo(){System.out.println("UserRepo");}
}@Service
public class UserService {public void doService() {System.out.println("UserService doService");}
}@Controller
public class helloTest {public void hello(){System.out.println("hello");}
}//启动类
@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringIocApplication.class, args);helloTest bean = context.getBean(helloTest.class);bean.hello();}}

这里我们只需要用相同的模板就可以实现这里的IOC操作

这里我们介绍一下getBean的几个参数

我们可以根据类型找到类,可以根据类型+方法名找到类,也可以只根据方法名寻找类

注意这里Bean的名字是以小驼峰的方式去拿的

比如HelloTest 这里的Bean名称就是 helloTest

注意这里获取到的三个对象都是同一个对象

类的命名规则:如果只有开头字母是大写的,那么我们就将第一个字母变成小写的,如果前两个都是大写字母,那么我们就直接返回这个名字

假设这里我们使用的类名是HElloTest,我们使用首字母小写小驼峰的方式就会直接失败

这里我们可以看到日志显示找不到这个Bean 实际上开头两个字母都大写Bean就不会修改名称,直接使用原名即可获取

使用的就是这个方法

注:idea中查询类 使用 ctrl + shift + alt + n

再查询方法可以使用ctrl + f查询

Application和BeanFactory之间的关系?

1.父子关系  BeanFactory有的功能Application都有

2.除此之外Application有很多其他的功能

3.BeanFactory是一个懒加载的方式  

Application是一个预加载的方式,效率更高

五大注解的对比

我们看到除了component其他的四大注解基本上都是一样的

可以混用嘛??

理论上可以,但是工作中一般不允许混用,但是其中的界限分割的不明确,有的时候还是混用的

@Controller   @Conponent  主键

@Service 业务逻辑层  @Repository  数据层 @Configuration  表现层

注:这里的Controller有特殊用处,其余三个可以在理论上混用(事实上也可以)

其余四个注解都包含了Component

注:@Controller如果进行替换不一定能实现路由映射

注:这里不加上注解时无法将对象交给Spring管理的

这里我将@Controller注解删除

Spring就会获取不到这个Bean

下面开始使用Bean的方式书写

注意:@Bean的使用也需要配合五大注解一起使用

Spring不可能扫描所有的项目文件,这里我们就使用五大注解来标识一下需要扫描的文件

@Bean的命名方式就是方法名

Spring扫描的默认是哪些文件呢?

我们先做一个测试,将启动类放到component包下

这时候去获取component的类就是可以的,获取HelloTest的类就是失败的

Spring扫描的三大条件

1.使用五大注解标记类

2.使用Bean注解标记方法

3.默认扫描路径是启动类所在的目录以及子目录 

如果我们向让其扫描其他的路径,就可以使用@ComponentScan(basePackages = "")

我们这样就可以获取User对象了

@Configuration
public class UserConfig {@Beanpublic User doConfig(){User u1 = new User();u1.setName("zhangsan");u1.setId(1001);return u1;}
}

DI注入

这里有三种方式注入

1.依赖注入/属性注入

2.构造器注入

3.setter注入

首先是依赖注入  我们只需要给需要交给Spring的对象加上五大注解,给需要注入的属性加上Autowired让他去Spring里面获取对应的对象即可

我们将注解干掉,使用构造器的方式也可以获取到

但是如果加上一个空参构造器,就会产生异常

这里出现空指针了,因为这里的Spring是调用构造函数来创建对象的,是使用反射的方式来操作的,这里有两个对应的构造函数了,默认就直接使用无参的构造函数了

如果我们再加一个属性和一个两个参数的构造函数

就会产生没有默认构造器的错误,这里我们可以使用@Autowired修饰默认构造方法解决

这样就可以正常运行啦

总结:

对于构造函数注入

1.只有一个构造函数的时候,无需操作

2.多个构造函数的时候需要@Autowired指定对应的构造函数

注:规范的写法是任何时候都把无参的构造函数加上,然后把想用的构造函数加上@Autowired注解即可

set方法+@autowired注解仍然可以完成任务

三种属性注入的优缺点

1.属性注入

优点是简洁并且书写方便

缺点也明显 只能用于IOC容器,使用的时候肯呢个出现空指针问题

不能注入final修饰的属性

2.构造器注入

优点:可以注入final修饰的属性

通用性好,JDK支持,所以任何框架都行

依赖对象使用前一定会被完全初始化

3.set方法注入

优点是方便在类实例之后重新堆起对象进行配置和注入

缺点是不能注入final修饰的属性

也可能被其他人修改

我们使用已有的bean来命名是可以正常执行内容的

但是只要我们改一下名字,立马就找不到对应的bean了

我们可以理解这里的查找方式是先根据类型和名称查询,查不到就根据类型查找,在没有就报错异常

这里可以使用三种方式去拿到对应的Bean对象

1.使用Primary注解给对应的Bean标记上,指定使用这个Bean

2.使用Qualifier注解,选出使用Bean的方法名

3.使用resourse注解加上方法名的方式也可以解决问题

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL数据库高级语句

文章目录 MySQL高级语句older by 排序区间判断查询或与且(or 与and)嵌套查询(多条件)查询不重复记录distinctcount 计数限制结果条目limit别名as常用通配符嵌套查询(子查询)同表不同表嵌套查询还能用于删除…

ZYNQ学习之Ubuntu环境下的Shell与APT下载工具

基本都是摘抄正点原子的文章&#xff1a;<领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 一、Ubuntu Shell操作 简单的说Shell 就是敲命令。国内把 Linux 下通过命令行输入命令叫…

Python爬虫如何快速入门

写了几篇网络爬虫的博文后&#xff0c;有网友留言问Python爬虫如何入门&#xff1f;今天就来了解一下什么是爬虫&#xff0c;如何快速的上手Python爬虫。 一、什么是网络爬虫 网络爬虫&#xff0c;英文名称为Web Crawler或Spider&#xff0c;是一种通过程序在互联网上自动获取…

linux编程--文件系统处理常用函数

文件系统 这一个课程的笔记 文件存储相关的概念 文件描述主要有两个inode和dentry inode 是一个结构体, 里面有这一个文件的权限, 类型, 大小, 时间, 用户, 盘块位置之类的信息, 这一个是文件属性的管理结构 文件名是单独存储的, 可以使用inode的编号找到这一个结构体 创建一…

应急响应实战笔记04Windows实战篇(1)

第1篇&#xff1a;FTP暴力破解 0x00 前言 ​ FTP是一个文件传输协议&#xff0c;用户通过FTP可从客户机程序向远程主机上传或下载文件&#xff0c;常用于网站代码维护、日常源码备份等。如果攻击者通过FTP匿名访问或者弱口令获取FTP权限&#xff0c;可直接上传webshell&#…

ida调试技巧-通过修改zf寄存器的值绕过简单反调试

参考本篇->OllyDbg笔记-对标志寄存器中ZF的理解&#xff08;逆向方面&#xff09;_零标志位zf怎么判断-CSDN博客 不想看也没关系&#xff0c;蒟蒻博主概述一下&#xff0c;总之&#xff0c;在机器执行汇编指令时&#xff0c;标志&#xff08;flag&#xff09;寄存器中的一个…

大模型新王诞生!Claude 3首次超越GPT4

一觉醒来&#xff0c;大模型世界迎来了“新王登基”&#xff01; 当地时间周三&#xff0c;聊天机器人竞技场Chatbot Arena更新对战排行榜&#xff0c;Claude 3反超GPT-4&#xff0c;一举摘得“最强王者”桂冠。 这次登顶榜首的是Claude 3系列的超大杯Opus&#xff0c;它以2分…

如何通过idea搭建一个SpringBoot的Web项目(最基础版)

通过idea搭建一个SpringBoot的Web项目 文章目录 通过idea搭建一个SpringBoot的Web项目一、打开idea&#xff0c;找到 create new project二、创建方式三、配置项目依赖四、新建项目模块五、总结 一、打开idea&#xff0c;找到 create new project 方式1 方式2 二、创建方式 新…

elasticsearch 6.8.x 索引别名、动态索引扩展、滚动索引

文章目录 引言索引别名&#xff08;alias&#xff09;创建索引别名查询索引别名删除索引别名重命名索引别名 动态索引&#xff08;index template&#xff0c;动态匹配生成索引&#xff09;新建索引模板新建索引并插入数据索引sys-log-202402索引sys-log-202403索引sys-log-202…

STM32 | Systick定时器(第四天源码解析)

STM32 | Systick定时器(第四天)STM32 | STM32F407ZE中断、按键、灯(续第三天)1、参考delay_us代码,完成delay_ms的程序 定时器频率换算单位:1GHZ=1000MHZ=1000 000KHZ = 1000 000 000HZ 定时器定时时间:计数个数/f(频率) 或者 (1/f(频率))*计数的个数 500/1MHZ = 500/1…

农田通量计算中的感热通量与潜热通量分析

地表水热通量主要包括感热/显热通量和潜热通量&#xff0c;是陆-气交互以及水-热-碳循环研究的重要变量。其中&#xff0c;潜热通量是地表蒸散发的能量形式&#xff0c;对农业水资源管理、作物水分利用效率等非常关键。由于热红外遥感对地表干湿变化、以及农业干旱响应快速&…

洗地机哪个好?专业对比,帮你选出比较适合的洗地机

随着科技的不断发展&#xff0c;洗地机已经成为了现代生活中不可或缺的清洁工具。然而&#xff0c;市面上涌现出各种各样的洗地机品牌&#xff0c;品质良莠不齐。因此&#xff0c;选择一个可靠的品牌至关重要&#xff0c;以确保产品质量和使用效果。为了帮助大家更好地选择&…

vulnhub靶场之driftingblues-3

一.环境搭建 1.靶场描述 get flags difficulty: easy about vm: tested and exported from virtualbox. dhcp and nested vtx/amdv enabled. you can contact me by email for troubleshooting or questions. This works better with VirtualBox rather than VMware 2.靶场…

python的一些知识点

在C C Java中&#xff0c;基本数据类型变量&#xff08;将常量数据存储在变量空间当中&#xff09; int a 3; int b 4; 在C C中&#xff0c;指针变量&#xff08;存储的是变量的物理内存地址&#xff09; int a 3; int* b; b &a; int** c; c &b; printf("%d&…

JAVA面试大全之并发篇

目录 1、并发基础 1.1、多线程的出现是要解决什么问题的? 本质什么? 1.2、Java是怎么解决并发问题的? 1.3、线程安全有哪些实现思路? 1.4、如何理解并发和并行的区别? 1.5、线程有哪几种状态? 分别说明从一种状态到另一种状态转变有哪些方式? 1.6、通常线程有哪几…

Web开发基本流程

Web是全球广域网&#xff0c;能够通过浏览器访问的网站。我们要访问网站&#xff0c;首先要在浏览器输入对应的域名。 浏览器也是一个程序&#xff0c;京东的网站也是一个程序&#xff0c;在京东那边电脑运行着&#xff0c;我们只是通过浏览器远程访问。京东的程序由三个部分组…

【生活】如何学习理财

文章目录 1. 了解基本财务知识2. 制定预算4321理财法则 3. 学习投资知识股票债券基金外汇房地产 4. 了解保险知识人身保险人寿保险健康保险意外伤害保险 财产保险财产损失保险责任保险信用保险 5. 寻求专业建议6. 持续学习和实践参考 首先我们想文心一言提问&#xff1a;如何学…

自媒体用ChatGPT批量洗稿软件V5.9环境配置/软件设置教程【汇总】

大家好&#xff0c;我是淘小白~ 首先&#xff0c;感谢大家的支持~~ ChatGPT采集洗稿软件V5.9版本更新&#xff0c;此次版本更新修改增加了一些内容&#xff1a; 1、自定义多条指令&#xff0c;软件自动判断指令条数&#xff0c;进行输入 2、增加谷歌浏览多账号轮询&#xf…

教育建筑智慧能源管理平台解决方案【新型电力系统下的绿色校园能源管理平台】

一、行业特点 1.建筑类型多&#xff1a;集教学、科研、生活于一体&#xff0c;占地面积大&#xff0c;建筑类型多&#xff0c;功能划分复杂。 2.供电可靠性要求高&#xff1a;教育建筑中的高层建筑、图书馆、实验楼等特级和一级负荷比较多&#xff0c;一旦发生故障会危及生命…

基于Python实现多功能翻译助手(下)

为了将上述步骤中的功能增强与扩展具体化为代码&#xff0c;我们将实现翻译历史记录功能、翻译选项配置以及UI的改进。 翻译历史记录功能 import json # 假设有一个用于存储历史记录的json文件 HISTORY_FILE translation_history.json # 初始化历史记录列表 translati…