返回顶部
首页 > 资讯 > 后端开发 > Python >Java SpringBoot的相关知识点详解
  • 129
分享到

Java SpringBoot的相关知识点详解

2024-04-02 19:04:59 129人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录1. ioc和DI2. spring容器加载Bean/创建对象的时机3. @Autowired注解4. @Configuration配置类5. @Conditional条件注解6

1. IOC和DI

首先,我们应该明确,IOC是一种思想,并不是Spring特有的,而是软件工程逐步发展的一种产物,是一种优秀的编程思想,之所以我们经常会把IOC理解成是Spring特有的东西,是因为Spring框架可以帮助我们很好的去实现IOC。IOC代表的是控制反转,控制的是什么?反转的是什么?控制的是一个对象的创建、初始化和销毁,没有使用IOC之前,我们使用一个对象,会主动的去创建对象,也就是在需要使用这个对象的地方去执行 A a = new A(); 类似这种语句,而使用了IOC之后,会把系统中所有需要使用到的对象交给IOC容器去托管,当我们的程序中需要使用到某个对象时,也不是我们直接去容器获取这个对象,而是容器会主动的给我们这个对象,也就是说IOC容器会自动给程序中需要对象的地方给你注入对象,这就是反转,把获取对象的行为由主动变为被动,并且把控制权交给了容器。

DI代表的是依赖注入,什么是依赖注入?我们都知道,对象与对象之间一般都会有依赖关系的,例如对象A依赖于对象B,对象B又依赖于对象C,举个例子,对象A中有个方法a,a方法的实现需要调用B对象的b方法,这就是依赖,引入IOC之前,我们会在A对象中new一个B对象,再通过B对象去调用b方法;引入IOC之后,我们都不会去主动创建对象了,都交给IOC容器去处理了,我们只需要在对象A中声明一个B对象的成员变量,加上xml配置或者相关注解,IOC容器就可以我们自动实现注入。例如下面这段代码,在mvc架构中,Controller层依赖Service层,我们只需要在Controller层声明一个Service层的变量,并加上@Autowired注解,当IOC容器启动时加载ApplicationController这个Bean到容器中时,会自动把ApplicationService这个Bean也注入进来。

请添加图片描述

依赖注入的实现方式有三种:构造函数注入、set方法注入以及接口注入;接口注入用的比较少,一般都是使用构造函数注入和set方法注入,另外还有一种字段注入,如上图所示的注入方式就是字段注入,这种注入方式不是规范的,可以看到@Autowired注解会给出警告,不建议我们使用这种方式,但这种方式却是使用最多的,因为它很方便。

请添加图片描述

以下是构造函数注入:

请添加图片描述

以下是set方法注入:

请添加图片描述

2. Spring容器加载Bean/创建对象的时机

默认情况下,程序启动的时候,Spring就会把程序中需要用到的Bean加载到IOC容器中,也就是会一次性创建很多的对象到IOC容器中。当然,还有一种方式,就是当需要使用到某个Bean的时候,再去创建这个Bean到容器中,这就是延迟加载,或者叫延迟实例化。

如果我们希望某个Bean不要过早的被加载到容器中,使用到的时候再去创建,可以给这个Bean加上@Lazy注解。

请添加图片描述

关于@Lazy注解实现延迟加载,需要注意一个细节,我们给某个Bean加上@Lazy注解之后,并不一定就能实现延迟加载,有可能程序在启动的时候,这个Bean还是会在一开始就被创建,会产生这种情况是因为这个Bean有可能在别处被引用到,也就是说别的Bean可能依赖了这个Bean,而依赖的这个Bean又没有打上@Lazy注解,那么程序启动的时候,创建这个依赖的Bean,也会把它所依赖的Bean一并注入,这就是导致@Lazy注解有时没有生效的原因。

举个例子,ApplicationController这个Bean依赖了ApplicationServiceImpl,我们只给ApplicationServiceImpl这个Bean加上@Lazy注解,是无法实现延迟加载的,需要ApplicationController这个Bean也加上@Lazy注解。

请添加图片描述

请添加图片描述

请添加图片描述

3. @Autowired注解

@Autowired注解的作用就是实现依赖注入,大部分情况下,我们使用@Autowired这个注解就可以满足我们的需求了,但是我们需要知道这个注解的约定是什么,才能更好的使用它。首先,@Autowired注解实现的是按照类型注入,补充一个点:为了满足ocp原则,使得代码更加灵活便于扩展,我们倡导面向接口编程。例如下面这个例子,ApplicationService是一个接口,我们加上了@Autowired注解,按照类型注入的原则,IOC容器会去找ApplicationService接口的实现类去进行依赖注入,如果这个接口只有一个实现类,那么没有问题,可以实现注入,如果这个接口有多个实现类,那么IOC容器会知道给我们注入哪一个实现类吗,显然是不知道的,但是@Autowired还有一种规则,就是根据类型匹配时,如果能匹配多个,会再根据Bean的名称去匹配,如果Bean的名称能匹配上,那么没有问题,可以实现注入;如果Bean的名称匹配不上,程序会报错,因为IOC容器不知道给我们注入哪一个ApplicationService接口的实现类。

请添加图片描述

举个例子,假设现在ApplicationService接口有两个实现类ApplicationServiceImpl1(Bean名称:applicationServiceImpl1)和ApplicationServiceImpl2(Bean名称:applicationServiceImpl2),如果@Autowired注解作用的代码是private ApplicationService applicationServiceImpl1;,那么注入的是ApplicationServiceImpl1这个Bean,如果@Autowired注解作用的代码是private ApplicationService applicationServiceImpl2;,那么注入的是ApplicationServiceImpl2这个Bean,如果@Autowired注解作用的代码是private ApplicationService applicationServiceImpl;,那么程序报错,IOC容器知道为我们注入哪个Bean。

如果涉及一个接口有多个实现类的情况,我们建议使用@Autowired注解搭配@Qualifier注解,@Qualifier注解的实现机制是按照Bean的名称进行注入。

例如下面这个例子,首先@Autowired注解会根据类型找到ApplicationService的实现类,@Qualifier注解再找到名称为applicationServiceImpl的Bean进行注入。

请添加图片描述

PS:上面我们讲的是@Autowired注解如果匹配到多个Bean不知道注入哪一个的时候会报错,还有一种情况,如果@Autowired注解匹配不到任何对应的Bean也会报错。

4. @Configuration配置类

一个类被加上了@Configuration注解,就表明这个类是一个配置类,@Configuration注解底层注解是@Component,也就是说,注解类也会被加载到IOC容器中,在注解类中,通常会声明很多方法,这些方法的返回值是一个对象,并且方法加上了@Bean注解,这表明会将这些方法返回的对象加载到IOC容器中。例如:

请添加图片描述

@Configuration注解是用来替换Bean的xml配置,可以把@Configuration看作标签,把@Bean注解看作标签

传统的xml配置是这样的:


<beans>    <bean id = "people", class = "com.test.People">    </bean>    <bean id = "student", class = "com.test.Student">    </bean></beans>

思考一个问题:一般来说,把一个Bean加载到IOC容器中,不是通过@Component注解就可以实现吗?况且@Configuration注解的底层注解还是@Component,那为什么还需要@Configuation+@Bean这套注解来加载某些Bean到IOC容器中呢?换言之,@Configuation+@Bean的真正作用是什么?

@Configuation+@Bean的作用就是可以将一些定制化的Bean(特殊的Bean)注入到IOC容器中,什么是定制化的Bean?举个例子,有一个People类,有两个属性name和age,我们希望把People类加载到IOC容器中,并且使得IOC容器的这个Bean的name属性值是小明,age属性值是18。如果只是在People类上加@Component注解,是无法实现我们这个定制化的Bean的,因为IOC容器在启动的时候,创建Bean,默认调用的都是某个类的无参构造函数(也存在调用带参构造函数的情况,但是这种情况使用带参构造函数,只是为了实现依赖注入,也就是构造函数注入,并非是给属性赋值),也就是说无法给我们的属性赋特殊的值,而使用@Configuation+@Bean就可以实现。例如:

请添加图片描述

请添加图片描述

通常来说,我们不会直接把属性值写死在代码里,而是通过读取配置文件的形式,虽然说@Configuration注解表明这个类已经是一个配置类了,可以充当配置文件来使用,但是对于一些变化的属性,我们都会定义在普通配置文件里面,例如application.properties。

请添加图片描述

请添加图片描述

5. @Conditional条件注解

@Conditional注解的作用是满足某个条件时,才会将这个Bean注入到IOC容器中。我们可以通过自定义一个Condition类的方式定制某个规则,当满足这个规则才会注入Bean,例如:

请添加图片描述

请添加图片描述

通常,我们直接使用一些成品条件注解就可以满足我们的需求了。常用成品条件注解如下:

请添加图片描述

6. SpringBoot的自动配置/自动装配

自动装配是SpringBoot最核心的东西,学习自动装配,我们首先应该了解自动装配是什么,做了哪些事情?其次需要明确自动装配存在的意义,也就是说自动装配的好处是什么?最后再去了解自动装配的原理。按照这个流程下来,才能更好的掌握自动装配这个知识点。

a. 自动装配做了什么事情? 就是SpringBoot会自动把一些第三方的库或者SDK需要使用到的很多Bean都自动帮我们加载到IOC容器中。

b. 自动装配的好处是什么? 基于IOC思想,任何程序中使用到的Bean都需要注入IOC容器中进行托管,也就是说,我们引用一些第三方的库/依赖,例如mongoDBRedishadoop,也是需要把这些第三方的库涉及的Bean都加载到IOC容器中的。如果没有自动装配,那么如何把第三方的库里面的很多Bean都加载到我们的IOC容器中来,给每一个相关的类打上@Component注解?不是这样的,我们所引用的第三方库一般都是以jar包的形式存在,并不是直接给源码。即便是可以通过打上@Component注解的方式,试想我们的工作量会增加多少,引用一个第三方库可能涉及很多的Bean,并且有些Bean又可能是比较复杂的,我们不可能手动的将他们一个个注入容器,而SpringBoot都帮我们做好了,这就是自动装配的好处。

c. 自动装配的原理

首先,在SpringBoot程序的主启动类上,有一个非常重要的注解:@SpringBootApplication,进入到这个注解,可以发现底层由三个注解组成(元注解除外)

请添加图片描述

@SpringBootConfiguration:表明SpringBoot程序的主启动类也是一个配置类

@ComponentScan:指定包扫描路径,程序启动时,会根据指定的包扫描路径去加载Bean

@EnableAutoConfiguration:最重要的一个注解,我们可以理解成这个注解的作用是开启自动装配

进入到@EnableAutoConfiguration,可以发现底层由两个注解组成(元注解除外)

请添加图片描述

我们主要研究@Import注解,这个注解有两种实现方式,第一种是指定一个或多个配置类,例如:@Import(TetsConfiguration.class) 那么IOC容器就会将这个配置类加载到容器中来,另一种实现方式是指定一个ImportSelector类的子类,例如@Import(AutoConfigurationImportSelector.class) 这个ImportSelector类的子类会去实现selectImports方法,该方法的返回值是一个字符串数组,代表要加载的配置类名称列表。

SpringBoot自动装配默认使用第二种方式,我们进到AutoConfigurationImportSelector这个类里面,发现它确实实现了selectImports方法。通过这个方法,SpringBoot就可以知道我们需要自动装配哪些配置类

请添加图片描述

我们再进入getAutoConfigurationEntry方法,这个方法里面有一个核心方法getCandidateConfigurations,翻译过来就是获取候选的配置类

请添加图片描述

getCandidateConfigurations方法实现逻辑就是:会去读取某一个配置文件,根据这个配置文件的值返回自动装配要装配的配置类名称列表

请添加图片描述

我们进入到SpringFactoriesLoader类,可以知道getCandidateConfigurations读取的配置文件就是META-INF下面的spring.factories

请添加图片描述

spring.factories的位置

请添加图片描述

spring.factories配置文件主要就声明了很多自动配置类的名称,截取部分如下:

请添加图片描述

总结一下,我们一路追踪源码下来,无非确定了一件事,SpringBoot自动装配时装配了哪些配置类,这些配置类的定义都存在于spring.factories配置文件中。

另外,我们需要明确,SpringBoot自动装配时也不是把所有自动配置类定义的Bean都加载到IOC容器中,因为这些Bean大部分都会加上条件注解,需要满足一定的条件才会被加载,例如,我们进入某一个自动配置类看一下

请添加图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java SpringBoot的相关知识点详解

本文链接: https://lsjlt.com/news/137552.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java SpringBoot的相关知识点详解
    目录1. IOC和DI2. Spring容器加载Bean/创建对象的时机3. @Autowired注解4. @Configuration配置类5. @Conditional条件注解6...
    99+
    2024-04-02
  • 详解java注解相关知识
    定义  1、如果注解中有属性,那么必须给属性赋值。 package com.lxc.Test; // 定义一个注解 public @interface Annota...
    99+
    2024-04-02
  • 详解Java接口的相关知识
    一、接口概述 接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法、成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前)、...
    99+
    2024-04-02
  • 有哪些Java的相关知识点
    这篇文章主要介绍“有哪些Java的相关知识点”,在日常操作中,相信很多人在有哪些Java的相关知识点问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”有哪些Java的相关知识点”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-16
  • HTML5相关知识点
    这篇文章主要介绍了HTML5相关知识点,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。SGML(标准通用标记语言)和HTML(超文本标记语言)...
    99+
    2024-04-02
  • java异常处理相关知识点
    这篇文章将为大家详细讲解有关java异常处理相关知识点,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。异常概述在Java中,这种在程序运行时可能出现的一些错误称为异常。异常是一个在程序执行期间发生的事件,它...
    99+
    2023-06-29
  • java Shiro相关知识点有哪些
    这篇文章主要介绍了java Shiro相关知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java Shiro相关知识点有哪些文章都会有所收获,下面我们一起来看看吧。1.权限的管理1.1 什么是权限管...
    99+
    2023-07-06
  • R语言中因子相关知识点详解
    因子是用于对数据进行分类并将其存储为级别的数据对象。 它们可以存储字符串和整数。 它们在具有有限数量的唯一值的列中很有用。 像“男性”,“女性”和True,False等。它们在统计建...
    99+
    2024-04-02
  • Java中的枚举相关知识点总结
    这篇文章主要讲解了“Java中的枚举相关知识点总结”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的枚举相关知识点总结”吧!Java中的枚举枚举通常是一组相关的常量集合,其他编程语言...
    99+
    2023-06-15
  • JAVA的IO流相关知识点有哪些
    今天小编给大家分享一下JAVA的IO流相关知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一.Input和Outp...
    99+
    2023-06-03
  • SwiftUI中@ViewBuilder的相关知识点解密
    前言 在SwiftUI框架中使用很多的注解,虽然使语法看上去非常简洁,但是增加了初学者的理解难度,这篇文章我们来看一下@ViewBuilder的相关知识。主要包括以下内容: ...
    99+
    2024-04-02
  • 详解SpringIOC容器相关知识
    目录一、前言二、IOC原理实战三、IOC本质四、spring helloworld五、小结一、前言 IOC控制反转,不是一种技术,而是一种设计思想,就是将原本在程序中手动创建对象的控...
    99+
    2024-04-02
  • Java中Volatile相关知识点有哪些
    这篇文章主要介绍“Java中Volatile相关知识点有哪些”,在日常操作中,相信很多人在Java中Volatile相关知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中Volatile相关...
    99+
    2023-06-16
  • HTML5拖拽的相关知识点
    本篇内容主要讲解“HTML5拖拽的相关知识点”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML5拖拽的相关知识点”吧!拖拽相关属性draggable属性是h...
    99+
    2024-04-02
  • 【字节面试】Fail-fast知识点相关知识点
    字节面试,问到的一个小知识点,这里做一下总结,其实小编之前有一篇文章,已经对此有过涉及,不过这里知识专项针对于问题,把这个知识点拎出来说一下。 1.问题 什么是Fail-fast机制? Hash...
    99+
    2023-08-31
    面试 java 字节 fail-fast Enumeration
  • HTML相关知识点总结
    目录简介HTML文档和网页的关系呢?HTML的标签样子?HTML基本概念标签元素属性注释编码规则HTML常用元素标题段落链接跳转页面:跳转锚点图片列表有序列表无序列表定义列表表格块表...
    99+
    2024-04-02
  • jdk 8 hashMap相关知识点
    1. compute、 computeIfAbsent、computeIfPresent 这三个是 Java Map 接口中的三个方法,用于对 Map 中的键值对进行操作。它们的区别在于执行的时机和操作的方式: compute(K key,...
    99+
    2023-10-12
    java 开发语言 hashMap
  • Java高并发的相关知识点有哪些
    本文小编为大家详细介绍“Java高并发的相关知识点有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java高并发的相关知识点有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。读到这里,这篇“Java高并发...
    99+
    2023-06-17
  • 详解Java注解知识点
    目录一、注解是什么二、jdk支持的注解有哪些2.1 三种常用的注解:2.2 元注解三、注解实例四、总结一、注解是什么 Java 注解用于为 Java 代码提供元数据,看完这句话也许你...
    99+
    2024-04-02
  • 关于python列表相关知识点
    目录python列表1.列表的创建与删除列表的特点1.列表元素按顺序有序排序2.索引映射唯一数据3.列表可以存储重复数据4.任意数据类型混存5.根据需要动态分配和回收内存2.列表的查...
    99+
    2023-05-16
    python python列表
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作