SpingBoot的5个扩展点
1、初始化器ApplicationContextInitializer
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033701-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033702-9846185b023b800.png)
new SpringApplication(SpringbootExtensionPointApplication.class).run(args);
老的只是包装了一个静态方法,实际底层就是实例化一个SpringApplication对象,然后调用它的run方法。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033703-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033704-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033705-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033706-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033708-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033709-9846185b023b800.png)
ApplicationContextInitializer
也已经注册上来了,变成8个了。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033710-9846185b023b800.png)
ApplicationContextInitializer
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033711-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033712-9846185b023b800.png)
run()
方法中的prepareContext()
方法中的applyInitializers()
方法,在这个方法中for循环的调用各个初始化器的initialize()
方法,从而我们就能看到把Jack的ApplicationContextInitializer
这句话给打印出来了。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033714-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033715-9846185b023b800.png)
2、监听器ApplicationListener
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033716-9846185b023b800.png)
ApplicationEventMulticaster
发布事件,各个Listener监听事件。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033717-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033718-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033719-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033721-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033722-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033723-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033724-9846185b023b800.png)
JackStartingApplicationListener
打个断点,然后看下堆栈信息![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033726-9846185b023b800.png)
SpringApplication run()
方法的listeners.starting()
开始进去发送ApplicationStartingEvent
广播事件,最后发布出去,由我们自己编写的事件监听器接收到。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033727-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033729-9846185b023b800.png)
ApplicationStartedEvent
事件也是一样的道理,通过打断点的方式来找到它的调用方,最后我们再来看下此时的扩展点图![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033730-9846185b023b800.png)
3、Runner
listeners.started()
后面有个callRunners![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033730-9846185b023b800-1.png)
ApplicationRunner
,还有一种是CommandLineRunner
,然后for循环的对它们进行调用,那么其实这个也是一个扩展点![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033731-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033733-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033734-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033735-9846185b023b800.png)
4、BeanFactoryPostProcessor
refreshContext()
方法![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033736-9846185b023b800.png)
refresh()
方法,这个方法里面就会做对容器的初始化。红框里的invokeBeanFactoryPostProcessors()
方法,这里也有一个扩展点,就是BeanFactoryPostProcessor
,执行对BeanFactory的后置处理。Spring Boot解析配置成BeanDefinition
的操作也是在此方法中。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033737-9846185b023b800.png)
BeanFactoryPostProcessor
,这个方法里面可以修改beanFactory的属性,beanfactory里面有BeanDefinition
,可以修改BeanDefinition
里面的值。BeanDefinition
是一个bean的元数据的信息,有多少个bean就有多少个BeanDefinition
。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033738-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033739-9846185b023b800.png)
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033741-9846185b023b800.png)
5、BeanPostProcessor
BeanPostProcessor
,它在通过反射构造函数进行bean实例化之后执行,那么红框里面标出来的registerBeanPostProcessors()
方法就是向BeanFactory
中注册beanpostprocessor
,用于后续bean创建的拦截操作。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033742-9846185b023b800.png)
BeanPostProcessor
,一共有两个方法,postProcessBeforeInitialization
和postProcessAfterInitialization
,不过我们一般用postProcessAfterInitialization
,在bean调用反射构造函数实例化之后执行。著名的应用场景AOP底层就是通过BeanPostProcessor
来实现的。![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033744-9846185b023b800.png)
postProcessAfterInitialization
上打个断点,看下堆栈信息是在哪里调用的![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033745-9846185b023b800.png)
finishBeanFactoryInitialization()
方法处调用的![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033746-9846185b023b800.png)
后记
![图片](https://www.ittce.com/wp-content/uploads/2024/02/1707033748-9846185b023b800.png)
微信赞赏
支付宝扫码领红包
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。侵权投诉:375170667@qq.com