01.关于@Import 和 @ImportResource
@Import注解用法(类上): 一般和@Configuration一起使用,用来导入里面@Bean方法返回的对象
@ImportResource(类上):一般和@Configuration一起使用,用来导入某个.XML文件里的bean
个人觉得这两个注解有点鸡肋
SpringBoot启动类默认扫描的是启动类包所在目录及其子包目录且SpringBoot启动类本身就是一个配置类
这是一个简单的SpringBoot项目,只引入了web,热部署和lombok
MyConfig1和启动类同包,MyConfig2不同包,myconfig3是个Spring的.xml文件
同包及子包下可以获取配置类的bean对象也可以获取到加了@Bean注解的对象(默认方法名)
但是要获取MyConfig2里的@Bean返回对象需要加@Import(MyConfig2.class),即使加了,你也不能获取到类对象
为什么说@Import(xxx.class)鸡肋呢?我用这个不行么?
02.关于SpringBoot的启动日志和失败分析器
启动日志如图 默认INFO级别
失败分析器 例如 我用插件方式再启动一次,提示端口被占用
将信息复制出来
***************************
APPLICATION FAILED TO START
***************************
Description: 这个是失败描述信息
Web server failed to start. Port 8080 was already in use.
Action: 这个是对该失败的修复意见
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.887 s
[INFO] Finished at: 2023-10-02T02:10:31+08:00
[INFO] ------------------------------------------------------------------------
Process finished with exit code 0
这个是由SpringBoot内置的失败分析器提供的
感觉这个就是在玩么........................
自定义一个失败分析器 继承 AbstractFailureAnalyzer<T>
另外操作
这拿来耍酷么???什么鬼东西
03.延迟初始化
Spring Boot 启动会默认实例化和初始化所有的单例(Singleton)Bean
当然预初始化是有好处的,不然也不会默认.
1.项目启动时就初始化了容器中所有的组件,因此后续提供服务时,速度更快.
2.启动就初始化应用所有组件,可提前发现项目中某个组件的错误.
------------------------------------------------------------------------------------------------------------
那么有些时候延迟初始化,或者说,需要某个Bean时候才去初始化.可以降低内存开销
延迟初始化的方式:
1.调用SpringApplicationBuilder对象的lazyInitialization(true)
针对SpringApplicationBuilder构建的Bean(刚学的就是全部是吧) 全局的
2.调用SpringApplication对象的setLazyInitialization(true) 全局的
3.在application.properties文件中配置 全局的
spring.main.lazy-initialization=true
下面演示三种全局延迟加载方式
创建一个类,定义无参构造
默认情况下启动就会被实例化,交给Spring容器管理
第一种方式:调用SpringApplicationBuilder对象的lazyInitialization(true)
修改启动类.可以看到TestController的构造并没有被调用
注意对于使用@Import或者@ImportResource 导入的Bean无效
用这两个注解导入的Bean可以用自己的配置方式:如xml的话 <bean>里可以指定延迟加载
第二种方式:调用SpringApplication对象的setLazyInitialization(true) 注意点和第一种方式一样
第三种就是
其实实际工作中,全局延迟加载用到的肯定少,除非真的内存不够
如何做局部或者单例的延迟加载呢
1.加上@Lazy注解
2.用@Conditional注解
这两个参数是啥自己查,挺好玩,有内涵
-
ConditionContext context
:表示条件的上下文,提供了有关当前条件的执行环境的信息。通过这个上下文,你可以访问 Spring 应用程序上下文、Bean 工厂以及其他条件相关的信息。 -
AnnotatedTypeMetadata metadata
:表示与条件关联的注解元数据。通过这个元数据,你可以获取与条件相关的注解信息,例如@Conditional
注解的属性等。
04.自定义Banner(这个大概了解,不想写)
在application.properties中
可以通过
spring.main.banner-mode属性对banner进行控制
console:表示在控制台输出
log:表示在日志文件输出
off:表示关闭Banner
05.设置SpringApplication
在SpringBoot的启动类中,我们一般都是
SpringApplication.run(类名.class,args)这种方式启动的,就是调用了SpringApplication的静态run方法,但是都没有对SpringApplication有多少了解.
ChatGPT大概这样解释:
SpringApplication是SpringBoot应用程序的启动引导类,封装了应用的启动过程,过程包括初始化Spring上下文,应用程序的配置,自动配置,组件扫描等 简化了SpringBoot应用程序的开发和部署.通过SpringApplication,开发人员可以轻松的创建,配置和启动SpringBoot引用程序
设置SpringApplication两种方式
1.通过SpringApplication对象的setter方法进行设置,然后调用run()实例方法启动SpringBoot应用
2.通过SpringApplicationBuilder的流式API进行设置,最后调用run方法启动SpringBoot应用
SpringApplicationBuilder是SpringApplication的构建器
先来感受下SpringApplication到底什么鬼
看样子SpringApplication就是用来在启动前,搞事情用的.
比如我这样就关闭了Banner
用SpringApplicationBuilder设置
注意:上面注释可能写的模糊了点.父容器,子容器,好比继承关系,并不是大装小的关系,可以比作多个Spring容器
效果是:父容器不能访问子容器,但是子容器可以访问父容器.
06.监听器
个人认为在SpringBoot中,监听器分为两种
1.监听SpringBootApplication的监听器
2.传统Spring监听器
1.监听SpringBootApplication的监听器
1.1)调用SpringApplication的addListeners()或SpringApplicationBuilder的Listeners()方法添 加事件
1.2)用META-INF/spring.factories文件来配置事件监听器.在该文件中添加如下代码即可注册 事件监听器 例如 org.springframework.context.ApplicationListener=xxx.xxx.xxx.MyListener
注意:META-INF/spring.factories
SpringApplication依次触发的事件
1.触发ApplicationStartingEvent事件
2.触发ApplicationEnvironmentPreparedEvent事件
3.触发ApplicationContextInitializedEvent事件
4.触发ApplicationPreparedEvent事件
5.触发ApplicationStartedEvent事件
该事件结束后才执行ApplicationRunner和CommandLineRunner两接口的回调函数
6.触发AvailabilityChangeEvent事件
7.触发ApplicationReadyEvent事件
8.触发AvailabilityChangeEven事件
9.触发ApplicationFailedEvent事件
事件这么多,但是我们如何使用监听器呢????
定义监听器
1.该监听器交由Spring管理
2.实现ApplicationListener接口泛型写你需要监听的事件
3.重写方法