运行引导类的main方法就可以启动项目。
如:properties、yaml、yml
都配置了同样的配置项,那么谁生效呢?
properties > yml > yaml
,读取了properties
的属性,其他两个的配置了相同的属性会被忽略掉,如果优先级低的配置文件里配置了优先级高的配置文件没有的属性,那么也会被读取识别。
一个一个手动注入
配置内容的键自动对应实体类对象的属性,配置文件的键需和实体类的属性名一致。
————————————————————————————————————————————————————————
功能:进行动态配置切换的。同一套程序会被安装到不同环境,如开发、测试、生产等。
激活
看4.1的激活部分
会覆盖文件激活方式
会覆盖文件激活方式
如多个地方都有配置文件,则都会加载,并互补
(classpath的根目录的配置文件配置了内容,而当前项目下的/config目录的配置文件没有配置,那程序会读取classpath根目录下的配置文件的配置项)。
配置文件内容
配置文件位置
加载配置文件
不用加任何参数,直接读取。如同级目录中有config文件夹并有配置文件,则会先加载config文件夹中的配置文件。
选择性创建Bean操作
类的判断定义为动态的,判断哪个字节码文件存在则可以动态指定。
第一步:自定义注解
第二步:使用自定义注解,来判断你需要判断的条件
内置的服务器有:
使用@Import导的类被Spring加载到IOC容器中,用法为
导入Bean
导入配置类
导入ImportSelector实现类,一般用于加载配置文件中的类
导入ImportBeanDefinitionRegistrar实现类
概括:
放在IOC容器中会被自动执行:
加上@Component
注解启动项目,只有两个监听器会被自动调用(ApplicationRunner、CommandLineRunner)
,这两个的作用、执行时机基本一样,只是参数不一样,ApplicationRunner
的参数是对象,CommandLineRunner
的参数是String可变参数。
需要配置才能生效:
在META-INF
中配置,在图标打印完后初始化,可以在项目还没有准备IOC容器之前检测资源是否存在。
SpringBoot启动时会触发不同的事件,在不同位置不同状态实现方法做不同的事情。没有构造方法会报错。
项目启动后执行
项目启动后执行
SpringBoot
启动流程分为两部分,第一部分初始化,第二部分启动应用。
源码分析:启动时调用SpringApplication
调用了run
方法,run
方法调用了本类的另一个静态方法,new
了SpringApplication
,又调用了该对象的run
方法,【new SpringApplication的初始化】
这里构造了SpringApplication
,它接收了两个参数,判断传递过来的primaySources
(引导类,可多个)是否为空,接着判断是否是web
环境(内部判断是不是有servlet
对应类的class
),接着设置初始化的initialzes
,设置listeners
,它去springFactories
中加载这两个东西,可以在this
里看到自定义的、系统提供的initialzes
。【SpringApplication.run启动应用
】启动时间控制,监控项目启动时间;定义了IOC容器context
;定义了Collection
集合,里面存放exceptionReporter
;注册了configureHeadlessProperty
;接着getRunListeners
,是一个容器,里面有很多定义了的Listener
,此时控制台没有任何打印信息,接着调用了listeners.starting
方法,starting
方法里拿到RunListener
集合,循环遍历调用每一个listener
的starting
方法,此时日志将输出在自定义Listener
的starting
中的打印信息。接着准备环境,封装环境参数在applicationArguments
对象中,此时回调了listeners.environmentPrepared
方法,里面也是循环遍历SpringApplicationRunListener
调用每一个environmentPrepared
,包括自己写的回调函数,此时控制台输出了自定义Listener
的environmentPrepared
中的打印信息。接着开始加载BeanInfo
,接着打印Banner
,支持自定义,可以通过BannerLocationProperty
属性定义打印信息的地址,如果项目中(resource)
存在banner.txt
文件,则会打印该文件的内容。接着创建applicationContest
(IOC容器),加载instances
,接着准备context
,此时触发了ApplicationContextRunListener的initialize
方法(初始化)、contextPrepared
方法(开始准备)、contextLoaded方法
(开始加载),此时IOC容器
创建完毕,但是beandefinitionMap
中的bean
还没有加载进来。接着refreshContext
,在这会才真正去配置里面找有哪些bean
要去创建,执行完了之后才加载进来。接着执行刷新afterRefresh
,然后停止监控项目启动时间。接着listeners.started
,然后项目启动成功了,它还会去执行相应的回调callRunners
,此时自定义的Runner
会被执行 。接着listenners.running
,最后return context
启动结束。