大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
1、什么是自动装配
自动装配就是把别人(官方)写好的config配置类加载到spring容器,然后根据这个配置类生成一些项目需要的bean对象。
(小声逼逼:就像我们自己在项目了写的config配置类一样的,只不过这个是别人写好的,你什么都不用管)
2、自动装配的开关在哪里
@SpringBootApplication
|--@EnableAutoConfiguration
|--@Import({
AutoConfigurationImportSelector.class})
在@SpringBootApplication
注解里的@EnableAutoConfiguration
用@Import
注解导入了一AutoConfigurationImportSelector.class
类,这个类的selectImports
方法会扫描我们类路径下的一个spring.factories文件(里面装的是很多官方写好的自动配置类的全限定名),然后返回这些类的名字。
- selectImports方法如下:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
- spring.factories文件的位置如下:
- spring.factories文件的内容如下:
3、自动装配开始(以tomcat为例)
前面的selectImports
函数会拿到 spring.factories文件
里的自动配置类,然后去解析这些配置类,这里以ServletWebServerFactoryAutoConfiguration
为例
这个类上面有很多条件注解,大致就是说当你的应用是web应用,符合spring MVC那一套,像什么Servlet啊等等,这个配置类才生效。其中这个配置类又用@Import
注解导入了几个类如下:
@Import({
ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
EmbeddedTomcat.class,
EmbeddedJetty.class,
EmbeddedUndertow.class})
这几个看名字就知道是什么,就是一些web容器嘛,Tomcat、Jetty、Undertow。其实EmbeddedTomcat.class
、EmbeddedJetty.class
、EmbeddedUndertow.class
是ServletWebServerFactoryConfiguration
里的三个静态内部类。
这里以EmbeddedTomcat.class
这个内部类为例,代码如下:
@ConditionalOnClass({
Servlet.class, Tomcat.class, UpgradeProtocol.class})
@ConditionalOnMissingBean(
value = {
ServletWebServerFactory.class},
search = SearchStrategy.CURRENT
)
static class EmbeddedTomcat {
EmbeddedTomcat() {
}
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers, ObjectProvider<TomcatContextCustomizer> contextCustomizers, ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.getTomcatConnectorCustomizers().addAll((Collection)connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatContextCustomizers().addAll((Collection)contextCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatProtocolHandlerCustomizers().addAll((Collection)protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));
return factory;
}
}
注意:第一行的 @ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class})
,这个条件注解表示你的类路径下有tomcat的依赖,即导入了Tomcat的jar包才会生效,EmbeddedTomcat.class
、EmbeddedJetty.class
也同理,但是只能有一个哈,导入了tomcat的jar包就不能导入其它的,不然会报错,当然了springboot默认tomcat,不需要我们导入。
这里会返回一个TomcatServletWebServerFactory
类,点进去后,其代码如下:
public class TomcatServletWebServerFactory
extends AbstractServletWebServerFactory
implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
其它代码不重要,哈哈。。。
这里继承了一个AbstractServletWebServerFactory
类, --------------AbstractServletWebServerFactory
类又继承了--------------AbstractConfigurableWebServerFactory
,
好,点击AbstractConfigurableWebServerFactory
进去就可以看到我们熟悉的8080
端口号了,如下:
3、结束语
其实springboot的自动装配还是比较复杂的,大概可以概括为:在启动类的run
方法传入启动类的class(方便后面获取其注解信息)。
执行run
方法,创建SpringApplication
对象,并用LoadSpringFactories()
方法将/META-INF/spring.factories
文件里的k-v读入缓存(方便后面加载时使用)。
然后继续run
方法,在某处会获取传入的启动类的class,并解析上面的注解,当解析到@Import({AutoConfigurationImportSelector.class})
时会将AutoConfigurationImportSelector加载进方法区,通过反射创建对象,调用其某一个方法,从缓存读取前面存储的k-v,并经过一系列的过滤、去重等,最后将需要的配置类加载,生成BD对象,创建Bean对象,放入spring容器。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234599.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...