目录
要搞清楚SpringBoot的自动配置原理,要从SpringBoot启动类上使用的核心注解@SpringBootApplication开始分析:
@SpringBootConfiguration注解上使用了@Configuration,表明SpringBoot启动类就是
@EnableAutoConfiguration注解(自动配置核心注解):
SpingBoot原理
配置优先级
优先级
: 命令行参数
>
系统属性参数
> properties
参数
> yml
参数
> yaml
参数
思考:如果项目已经打包上线了,这个时候我们又如何来设置
Java
系统属性和命令行参数呢?
java
-Dserver
.port
=
9000
-jar
XXXXX.jar
--server
.port
=
10010
下面我们来演示下打包程序运行时指定
Java
系统属性和命令行参数:
1.
执行
maven
打包指令
package
,把项目打成
jar
文件
2.
使用命令:
java -jar
方式运行
jar
文件程序
项目打包:


运行
jar
程序:
同时设置
Java
系统属性和命令行参数

仅设置
Java
系统属性

注意事项:
Springboot
项目进行打包时,需要引入插件
spring-boot-maven-plugin (
基于官网
骨架创建项目,会自动添加该插件
)
Bean管理
在前面的课程当中,我们已经讲过了我们可以通过
Spring
当中提供的注解
@Component
以及它的三个衍生注解(@Controller
、
@Service
、
@Repository
)来声明
IOC
容器中的
bean
对象,同时我们也学习了如何为应用程序注入运行时所需要依赖的bean
对象,也就是依赖注入
DI
。
我们今天主要学习
IOC
容器中
Bean
的其他使用细节,主要学习以下三方面:
1.
如何从
IOC
容器中手动的获取到
bean
对象
2. bean
的作用域配置
3.
管理第三方的
bean
对象
获取Bean
默认情况下,
SpringBoot
项目在启动的时候会
自动
的创建
IOC
容器
(
也称为
Spring
容器
)
,并且在启动的过程当中会
自动
的将bean
对象都创建好,存放在
IOC
容器当中。应用程序在运行时需要依赖什么
bean对象,就直接进行依赖注入就可以了。
而在
Spring
容器中提供了一些方法,可以主动从
IOC
容器中获取到
bean
对象,下面介绍
3
种常用方式:
1.
根据
name
获取
bean
Object
getBean
(
String
name
)
2.根据类型获取bean
<
T
>
T
getBean
(
Class
<
T
>
requiredType
)
3.
根据
name
获取
bean
(带类型转换)
<
T
>
T
getBean
(
String
name
,
Class
<
T
>
requiredType
)
思考:要从
IOC
容器当中来获取到
bean
对象,需要先拿到
IOC
容器对象,怎么样才能拿到
IOC
容器呢?
想获取到
IOC
容器,直接将
IOC
容器对象注入进来就可以了


Bean作用域
在前面我们提到的
IOC
容器当中,
默认bean对象是单例模式(只有一个实例对象)
。那么如何设置
bean对象为非单例呢?需要设置bean
的作用域。
在
Spring
中支持五种作用域,后三种在
web
环境才生效:

知道了
bean
的
5
种作用域了,我们要怎么去设置一个
bean
的作用域呢?
可以借助
Spring
中的
@Scope
注解来进行配置作用域


注意事项:
IOC
容器中的
bean
默认使用的作用域:
singleton (
单例
)
默认
singleton
的
bean
,在
容器启动时被创建
,可以使用
@Lazy注解
来延迟初始化
(
延迟到
第一次使用时
)

注意事项:
prototype
的
bean
,每一次使用该
bean
的时候都会创建一个新的实例
实际开发当中,
绝大部分的Bean是单例的
,也就是说绝大部分
Bean
不需要配置
scope
属性
第三方Bean
学习完
bean
的获取、
bean
的作用域之后,接下来我们再来学习第三方
bean
的配置。
之前我们所配置的
bean
,像
controller
、
service
,
dao
三层体系下编写的类,这些类都是我们在项
目当中自己定义的类
(
自定义类
)
。当我们要声明这些
bean
,也非常简单,我们只需要在类上加上
@Component
以及它的这三个衍生注解(
@Controller
、
@Service
、
@Repository
),就可以来声
明这个
bean
对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的。


那么我们应该怎样使用并定义第三方的
bean
呢?
如果要管理的
bean
对象来自于第三方(不是自定义的),是无法用
@Component
及衍生注解声明
bean
的,就需要用到
@Bean
注解。



说明
:以上在
启动类中声明第三方Bean的作法
,
不建议使用
(
项目中要保证启动类的纯粹性
)



SpringBoot原理
SpringBoot
使我们能够集中精力地去关注业务功能的开发,而不用过多地关注框架本身的配置使用。而我们前面所讲解的都是面向应用层面的技术,接下来我们开始学习SpringBoot
的原理,这部分内容偏向于底层的原理分析。
在剖析
SpringBoot
的原理之前,我们先来快速回顾一下我们前面所讲解的
Spring
家族的框架。

Spring
是目前世界上最流行的
Java
框架,它可以帮助我们更加快速、更加容易的来构建
Java
项目。而在Spring
家族当中提供了很多优秀的框架,而所有的框架都是基于一个基础框架的
SpringFramework(
也就是
Spring
框架
)
。而前面我们也提到,如果我们直接基于
Spring
框架进行项
目的开发,会比较繁琐。
这个繁琐主要体现在两个地方:
1.
在
pom.xml
中依赖配置比较繁琐,在项目开发时,需要自己去找到对应的依赖,还需要找到依赖
它所配套的依赖以及对应版本,否则就会出现版本冲突问题。
2.
在使用
Spring
框架进行项目开发时,需要在
Spring
的配置文件中做大量的配置,这就造成
Spring
框架入门难度较大,学习成本较高。

基于
Spring
存在的问题,官方在
Spring
框架
4.0
版本之后,又推出了一个全新的框架:SpringBoot。
通过
SpringBoot
来简化
Spring
框架的开发
(
是简化不是替代
)
。我们直接基于
SpringBoot
来
构建
Java
项目,会让我们的项目开发更加简单,更加快捷。
SpringBoot
框架之所以使用起来更简单更快捷,是因为
SpringBoot
框架底层提供了两个非常重要的
功能:
一个是起步依赖,一个是自动配置。

通过
SpringBoot
所提供的起步依赖,就可以大大的简化
pom
文件当中依赖的配置,从而解决了
Spring
框架当中依赖配置繁琐的问题。
通过自动配置的功能就可以大大的简化框架在使用时
bean
的声明以及
bean
的配置。我们只需要引
入程序开发时所需要的起步依赖,项目开发时所用到常见的配置都已经有了,我们直接使用就可以
了。
起步依赖
如果我们使用了
SpringBoot
,就不需要像上面这么繁琐的引入依赖了。我们只需要引入一个依赖就可以了,那就是web
开发的起步依赖:
springboot-starter-web
。

为什么我们只需要引入一个
web
开发的起步依赖,
web
开发所需要的所有的依赖都有了呢?
因为Maven的依赖传递。

结论:起步依赖的原理就是Maven的依赖传递。
自动配置
SpringBoot
的自动配置就是当
Spring
容器启动后,一些配置类、
bean
对象就自动存入到了
IOC
容器
中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。


自动配置原理
思考:引入进来的第三方依赖当中的
bean
以及配置类为什么没有生效?
• 原因在我们之前讲解IOC
的时候有提到过,在类上添加
@Component
注解来声明
bean
对象时,还需要保证@Component
注解能被
Spring
的组件扫描到。
• SpringBoot项目中的
@SpringBootApplication
注解,具有包扫描的作用,但是它只会扫描启
动类所在的当前包以及子包。
• 当前包:
com.itheima
, 第三方依赖中提供的包:
com.example
(
扫描不到
)
那么如何解决以上问题的呢?
方案1:@ComponentScan 组件扫描

缺点:
1.
使用繁琐
2.
性能低
方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)
1).
使用
@Import
导入普通类:

2).
使用
@Import
导入配置类:



3).
使用
@Import
导入
ImportSelector
接口实现类:



4).
使用第三方依赖提供的
@EnableXxxxx
注解

原理分析
源码跟踪技巧:
在跟踪框架源码的时候,一定要抓住关键点,找到核心流程。一定不要从头到尾一行代码去看,一
个方法的去研究,一定要找到关键流程,抓住关键点,先在宏观上对整个流程或者整个原理有一个
认识,有精力再去研究其中的细节。
要搞清楚SpringBoot的自动配置原理,要从SpringBoot启动类上使用的核心注解@SpringBootApplication开始分析:


@SpringBootConfiguration注解上使用了@Configuration,表明SpringBoot启动类就是
一个配置类。
@Indexed
注解,是用来加速应用启动的(不用关心)。

@ComponentScan注解:

@ComponentScan
注解是用来进行组件扫描的,扫描启动类
所在的包及其子包下所有被
@Component及其衍生注解声明的类。
SpringBoot
启动类,之所以
具备扫描包功能
,就是因为包含了
@ComponentScan
注解。
@EnableAutoConfiguration注解(自动配置核心注解):
使用@Import注解,导入了实现ImportSelector接口的实现类。
AutoConfigurationImportSelector类是ImportSelector接口的实现类。
AutoConfigurationImportSelector
类中重写了
ImportSelector
接口的
selectImports()
方
法:
selectImports()
方法底层调用
getAutoConfigurationEntry()
方法,获取可自动配置的
配置类信息集合
getAutoConfigurationEntry()
方法通过调用
getCandidateConfigurations(annotationMetadata, attributes)
方法获取在配置文
件中配置的所有自动配置类的集合
getCandidateConfigurations
方法的功能:
获取所有基于
META
INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imp
orts
文件、
META-INF/spring.factories
文件中配置类的集合
META-
INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件和
META-INF/spring.factories
文件这两个文件在哪里呢?
通常在引入的起步依赖中,都有包含以上两个文件





自动配置源码小结
@Conditional



所谓
starter
指的就是
SpringBoot
当中的起步依赖。在
SpringBoot
当中已经给我们提供了很多的起步依赖了,我们为什么还需要自定义 starter
起步依赖?这是因为在实际的项目开发当中,我们可能会用到很多第三方的技术,并不是所有的第三方的技术官方都给我们提供了与SpringBoot
整合的
starter
起步依赖,但是这些技术又非常的通用,在很多项目组当中都在使用。


首先我们先来创建两个
Maven
模块:
1). aliyun-oss-spring-boot-starter
模块
按照我们之前的分析,是需要在
starter
模块中来引入
autoconfigure
这个模块的。打开
starter
模
块中的
pom
文件:

2). aliyun-oss-spring-boot-autoconfigure
模块

答案:没用了。 在
SpringBoot
项目中,并不会去扫描
com.aliyun.oss
这个包,不扫描这个包那
类上的注解也就失去了作用。





Web后端开发总结
而为了实现三层架构层与层之间的
解耦
,我们学习了
Spring
框架当中的第一大核心:
IOC
控制反转与
DI依赖注入。
所谓控制反转,指的是将对象创建的控制权由应用程序自身交给外部容器,这个容器就是我们常说
的
IOC
容器或
Spring
容器。
而
DI
依赖注入指的是容器为程序提供运行时所需要的资源。
在
Spring
框架的生态中,对
web
程序开发提供了很好的支持,如:全局异常处理器、拦截器这些都是Spring框架中
web
开发模块所提供的功能,而
Spring
框架的
web
开发模块,我们也称为:
SpringMVC
SpringMVC
不是一个单独的框架,它是
Spring
框架的一部分,是
Spring
框架中的
web
开发模
块,是用来简化原始的
Servlet
程序开发的。
外界俗称的
SSM
,就是由:
SpringMVC
、
Spring Framework
、
Mybatis
三块组成。
基于传统的
SSM
框架进行整合开发项目会比较繁琐,而且效率也比较低,所以在现在的企业项目开发当中,基本上都是直接基于SpringBoot
整合
SSM
进行项目开发的。