1. 配置优先级 配置文件优先级排名(从高到低): 1. properties 配置文件 2. yml 配置文件 3. yaml 配置文件 在 SpringBoot 项目当中除了以上 3 种配置文件外, SpringBoot 为了增强程序的扩展性,除了支持配置文件的配置方式以外,还支持另外两种常见的配置方式: 1. Java 系统属性配置 (格式: -Dkey=value ) 2. 命令行参数 (格式: --key=value ) 优先级: 命令行参数 > 系统属性参数 > properties 参数 > yml 参数 > yaml 参数 注意事项: Springboot 项目进行打包时,需要引入插件 spring-boot-maven-plugin ( 基于官网 骨架创建项目,会自动添加该插件 ) 2. Bean 管理 2.1 获取 Bean 1. 根据 name 获取 bean 2. 根据类型获取 bean 3. 根据 name 获取 bean (带类型转换) 问题:输出的 bean 对象地址值是一样的,说明 IOC 容器当中的 bean 对象有几个? 答案:只有一个。 (默认情况下, IOC 中的 bean 对象是单例) 那么能不能将 bean 对象设置为非单例的 ( 每次获取的 bean 都是一个新对象 ) ? 可以,在下一个知识点 (bean 作用域 ) 中讲解。 注意事项: 上述所说的 【 Spring 项目启动时,会把其中的 bean 都创建好】还会受到作用域及延迟初始化影 响,这里主要针对于默认的单例非延迟加载的 bean 而言。 2.2 Bean 作用域 在 Spring 中支持五种作用域,后三种在 web 环境才生效: 借助 Spring 中的 @Scope 注解来进行配置作用域 注意事项: IOC 容器中的 bean 默认使用的作用域: singleton ( 单例 ) 默认singleton 的 bean ,在容器启动时被创建,可以使用 @Lazy 注解来延迟初始化 ( 延迟到第一次使用时) prototype 的 bean ,每一次使用该 bean 的时候都会创建一个新的实例实际开发当中,绝大部分的Bean 是单例的,也就是说绝大部分 Bean 不需要配置 scope 属性 2.3 第三方 Bean 第三方提供的类是只读的。无法在第三方类上添加 @Component 注解或衍生注解。 解决方案 1 :在启动类上添加 @Bean 标识的方法 说明:以上在启动类中声明第三方 Bean 的作法,不建议使用(项目中要保证启动类的纯粹性) 解决方案 2 :在配置类中定义 @Bean 标识的方法 注意事项 : 通过 @Bean 注解的 name 或 value 属性可以声明 bean 的名称,如果不指定,默认 bean 的名称 就是方法名。 如果第三方 bean 需要依赖其它 bean 对象,直接在 bean 定义方法中设置形参即可,容器会根 据类型自动装配 3. SpringBoot 原理 通过 SpringBoot 所提供的起步依赖,就可以大大的简化 pom 文件当中依赖的配置,从而解决了 Spring 框架当中依赖配置繁琐的问题。 通过自动配置的功能就可以大大的简化框架在使用时 bean 的声明以及 bean 的配置。我们只需要引 入程序开发时所需要的起步依赖,项目开发时所用到常见的配置都已经有了,我们直接使用就可以 了。 3.1 起步依赖 假如我们没有使用 SpringBoot ,用的是 Spring 框架进行 web 程序的开发,此时我们就需要引入 web 程 序开发所需要的一些依赖。 spring-webmvc 依赖:这是 Spring 框架进行 web 程序开发所需要的依赖 servlet-api 依赖: Servlet 基础依赖 jackson-databind 依赖: JSON 处理工具包 如果要使用 AOP ,还需要引入 aop 依赖、 aspect 依赖 项目中所引入的这些依赖,还需要保证版本匹配,否则就可能会出现版本冲突问题。 如果我们使用了 SpringBoot ,就不需要像上面这么繁琐的引入依赖了。我们只需要引入一个依赖就可以了,那就是web 开发的起步依赖: springboot-starter-web 。 在 SpringBoot 给我们提供的这些起步依赖当中,已提供了当前程序开发所需要的所有的常 见依赖 ( 官网地址: https://docs.spring.io/springboot/docs/2.7.7/referen ce/htmlsingle/#using.build-systems.starters ) 。 比如: springboot-starter-web ,这是 web 开发的起步依赖,在 web 开发的起步依赖当 中,就集成了web 开发中常见的依赖: json 、 web 、 webmvc 、 tomcat 等。我们只需要引入 这一个起步依赖,其他的依赖都会自动的通过Maven 的依赖传递进来。 结论:起步依赖的原理就是 Maven 的依赖传递。 3.2 自动配置 3.2.1 概述 SpringBoot 的自动配置就是当 Spring 容器启动后,一些配置类、 bean 对象就自动存入到了 IOC 容器 中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。 比如:我们要进行事务管理、要进行 AOP 程序的开发,此时就不需要我们再去手动的声明这些 bean 对象了,我们直接使用就可以从而大大的简化程序的开发,省去了繁琐的配置操作。 配置类最终也是 SpringIOC 容器当中的一个 bean 对象 比如:配置类 GsonAutoConfiguration 里面有一个 bean , bean 的名字叫 gson ,它的类型是 Gson 。 com.google.gson.Gson 是谷歌包中提供的用来处理 JSON 格式数据的。 当我们想要使用这些配置类中生成的 bean 对象时,可以使用 @Autowired 就自动注入了: 3.2.2 常见方案 3.2.2.1 概述 引入进来的第三方依赖当中的 bean 以及配置类没有生效 3.2.2.2 方案一 @ComponentScan 组件扫描 大家可以想象一下,如果采用以上这种方式来完成自动配置,那我们进行项目开发时,当需要引入 大量的第三方的依赖,就需要在启动类上配置 N 多要扫描的包,这种方式会很繁琐。而且这种大面 积的扫描性能也比较低。 缺点: 1. 使用繁琐 2. 性能低 结论: SpringBoot 中并没有采用以上这种方案。 3.2.2.3 方案二 @Import 导入 导入形式主要有以下几种: 1. 导入普通类 2. 导入配置类 3. 导入 ImportSelector 接口实现类 1). 使用 @Import 导入普通类: 2). 使用 @Import 导入配置类: 3). 使用 @Import 导入 ImportSelector 接口实现类: 结论:我们不用自己指定要导入哪些 bean 对象和配置类了,让第三方依赖它自己来指定。 怎么让第三方依赖自己指定 bean 对象和配置类? 比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以 @EnableXxxx 开头的注 解,注解中封装的就是 @Import 注解 4). 使用第三方依赖提供的 @EnableXxxxx 注解 3.2.3 原理分析 3.2.3.1 源码跟踪 源码跟踪技巧: 在跟踪框架源码的时候,一定要抓住关键点,找到核心流程。一定不要从头到尾一行代码去看,一 个方法的去研究,一定要找到关键流程,抓住关键点,先在宏观上对整个流程或者整个原理有一个 认识,有精力再去研究其中的细节。 自动配置原理源码入口就是 @SpringBootApplication 注解,在这个注解中封装了 3 个注解,分别 是: @SpringBootConfiguration 声明当前类是一个配置类 @ComponentScan 进行组件扫描( SpringBoot 中默认扫描的是启动类所在的当前包及其子包) @EnableAutoConfiguration 封装了 @Import 注解( Import 注解中指定了一个 ImportSelector 接口的实现类) 在实现类重写的 selectImports() 方法,读取当前项目下所有依赖 jar 包中 META INF/spring.factories 、 META INF/spring/org.springframework.boot.autoconfigure.AutoConfigurat ion.imports 两个文件里面定义的配置类(配置类中定义了 @Bean 注解标识的方法)。 当 SpringBoot 程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息 ( 类的全限定 名 ) 封装到 String 类型的数组中,最终通过 @Import 注解将这些配置类全部加载到 Spring 的 IOC 容器 中,交给 IOC 容器管理。 最后呢给大家抛出一个问题:在 META INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imp orts 文件中定义的配置类非常多,而且每个配置类中又可以定义很多的 bean ,那这些 bean 都会 注册到 Spring 的 IOC 容器中吗? 答案:并不是。 在声明 bean 对象时,上面有加一个以 @Conditional 开头的注解,这种注解的 作用就是按照条件进行装配,只有满足条件之后,才会将 bean 注册到 Spring 的 IOC 容器中(下面 会详细来讲解) 3.2.3.2 @Conditional @Conditional 注解: 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的 bean 对象到 Spring 的 IOC 容 器中。 位置:方法、类 @Conditional 本身是一个父注解,派生出大量的子注解: @ConditionalOnClass :判断环境中有对应字节码文件,才注册 bean 到 IOC 容器。 @ConditionalOnMissingBean :判断环境中没有对应的 bean( 类型或名称 ) ,才注册 bean 到 IOC 容器。 @ConditionalOnProperty :判断配置文件中有对应属性和值,才注册 bean 到 IOC 容器。 最后再给大家梳理一下自动配置原理: 自动配置的核心就在 @SpringBootApplication 注解上, SpringBootApplication 这个注解 底层包含了 3 个注解,分别是: @SpringBootConfiguration @ComponentScan @EnableAutoConfiguration @EnableAutoConfiguration 这个注解才是自动配置的核心。 它封装了一个 @Import 注解, Import 注解里面指定了一个 ImportSelector 接口的实现 类。 在这个实现类中,重写了 ImportSelector 接口中的 selectImports() 方法。 而 selectImports() 方法中会去读取两份配置文件,并将配置文件中定义的配置类做为 selectImports() 方法的返回值返回,返回值代表的就是需要将哪些类交给 Spring 的 IOC 容器进行管理。 那么所有自动配置类的中声明的 bean 都会加载到 Spring 的 IOC 容器中吗 ? 其实并不会,因 为这些配置类中在声明 bean 时,通常都会添加 @Conditional 开头的注解,这个注解就是进 行条件装配。而 Spring 会根据 Conditional 注解有选择性的进行 bean 的创建。 @Enable 开头的注解底层,它就封装了一个注解 import 注解,它里面指定了一个类,是 ImportSelector 接口的实现类。在实现类当中,我们需要去实现 ImportSelector 接口当中的一个方法 selectImports 这个方法。这个方法的返回值代表的就是我需要将 哪些类交给 spring 的 IOC 容器进行管理。 此时它会去读取两份配置文件,一份儿是 spring.factories ,另外一份儿是 autoConfiguration.imports 。而在 autoConfiguration.imports 这份儿文件 当中,它就会去配置大量的自动配置的类。 而前面我们也提到过这些所有的自动配置类当中,所有的 bean 都会加载到 spring 的 IOC 容器当中吗?其实并不会,因为这些配置类当中,在声明 bean 的时候,通常会加上 这么一类 @Conditional 开头的注解。这个注解就是进行条件装配。所以 SpringBoot 非 常的智能,它会根据 @Conditional 注解来进行条件装配。只有条件成立,它才会声明这 个 bean ,才会将这个 bean 交给 IOC 容器管理。
标签:依赖,SpingBoot,Spring,配置,bean,注解,原理,IOC From: https://blog.csdn.net/weixin_72952570/article/details/142901243