SpringBoot

自动装配原理

从Spring的IOC到SpringBoot的自动装配原理

DeferedImportSelector对Bean加载顺序的影响(当然是由@Import导入的)

 

 DeferedImportSelector有一个分组的概念,如果自定义了一个类,实现了Group接口,可以在这里面自定义排序规则。

 

 

 

 Group有延迟的特性,还有分组的特性。

扫描读取所有jar包当中的spring.factories文件,将文件中得配置读取到缓存中,为Map结构。

在这个过程,会排除和过滤掉不需要的自动配置类。

排除在EnableAutoConfiguration中可以配置要排除的自动配置类。

过滤则主要通过扫描spring.factories文件,找到对应key为:AutoConfigurationImportFilter,把对应配置了该key的配置类给过滤掉。比如:

比如有:@conditionalOnBean、@conditionalOnClass、@conditionalOnProperty 

有时候要求要有相应配置或者项目中有相关类才配加载自动配置。

最后扫描了之后可以在DeferedImportSelector的selectImports()方法中进行排序了。sortAutoConfigurations。

所以也可以自定义一个starter。

启动原理

为什么SpringBoot的jar可以直接运行?

Java没有提供任何标准的方式来加载嵌套的jar文件。(即它们本身包含在jar中的jar文件)

用我自己的话来说,maven通过将多个maven-jar的插件,将依赖的jar文件打包到目标的jar包里面,以及会生成一个MAINFESTMF的文件,然后运行java -jar的时候会运行JarLauncher,之后通过反射,找到MAINFEST.MF文件中的启动类,通过反射调用,执行main方法,启动spring boot程序。

总结:

JarLauncher通过BOOT-INF/classes目录以及BOOT-INF/lib目录下jar文件,实现了fat jar的启动。

SpringBoot通过扩展JarFile、JarURLConnection以及URLStreamHandler,实现了jar in jar中资源的加载。

SpringBoot通过扩展URLClassLoader-LauncherURLClassLoader,实现了jar in jar中class文件的加载。

启动类new 一个spring 上下文对象干了什么事情?

总结:

1. 获取启动类;根据启动类加载IOC容器。

2. 获取web应用类型;

3. spring.factories读取了对外扩展的ApplicationContextInitializer,ApplicationListener(对外扩展,对内解耦,比如全局配置文件、热部署插件)

4. 根据main推算出所在的类。

具体执行run方法流程:

读取配置文件(通过监听者模式)

读取配置类,

解析配置类,加载spring容器,解析@component,@Bean等注册为BeanDefinition,然后创建为一个真正的Bean

 SpringBoot是如何启动内置Tomcat的?

类似如下逻辑:

 

 在selfInstialize(ServletContext servletContext)方法中可以获得DispatcherServlet,但是DispatcherServlet怎么来的呢?

有一个DispatcherServletAutoConfiguration的类,这里面自动注入的。而注册DispatcherServlet为Bean主要用的是ServletRegistryBean。而它又实现了ServletContextInitializer接口。

 

 所以,在selfInstialize(ServletContext servletContext)中可以获得DispatcherServlet.

 

 外置Tomcat是如何启动SpringBoot的?

 由Tomcat通过SPI机制,读取ServletContainerInitializer的实现类:SpringServletContainerInitializer,进入该方法,要求Tomcat找到所有实现了WebApplicationInitializer的类,其中包括Dispatcher的。

 

 在调用对应的onStartUp方法

 

 在里面就注册了DispatcherServlet。而启动应用程序main方法用的就是SpringBootServletInitializer。

使用外置的Tomcat,除了要排除内置Tomcat依赖之外,还需要重写一个SpringBootServletInitializer对应接口的实现类:从而告诉tomcat应用程序的自动类是哪个

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   君莫笑我十年游  阅读(133)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示