Java SpringBoot自动装配原理详解
作者:技术专家--Felix
自动装配的含义
在SpringBoot程序main方法中,添加@SpringBootApplication或者@EnableAutoConfiguration会自动去maven中读取每个starter中的spring.factories文件,该文件里配置了所有需要被创建的Spring容器中的bean;
如图为springboot提供的starter自动配置:
springboot应用程序启动类
启动类一般通过@SpringBootApplication一个注解即可完成所有启动工作。
并且启动类要在项目最外层:
@SpringBootApplication注解分析
SpringBootApplication注解之所以强大的原因是其内部已经注入了三个注解:
@SpringBootConfiguration
此注解实际上就是@Configuration注解,用来标注配置类。
而@Configuration注解,内部又有@Component注解, 意味也将会注册为bean, 其内部也可以依赖注入。
@ComponentScan
这个注解也是Spring中的,它用来将指定包下需要装配的组件扫描出来注册到容器中。
创建一个配置类,在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类。
@EnableAutoConfiguration
此注解是自动装配的核心注解, @EnableAutoConfiguration的内部如图,其中有注解@AutoConfigurationPackage和@Import两个注解。
可以看到@Import注解内有一个类AutoConfigurationImportSelector。这个类(implement ImportSelector),实现了selectImports() 方法,用来筛选被@Import的Configuration类(减去exclude等)。
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { // 如果AutoConfiguration没开,返回{} if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } // 将spring-autoconfigure-metadata.properties的键值对配置载入到PropertiesAutoConfigurationMetadata对象中并返回 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); // 基于各种配置计算需要import的configuration和exclusion AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
可见selectImports()
是AutoConfigurationImportSelector
的核心函数,其核心功能就是获取spring.factories
中EnableAutoConfiguration
所对应的Configuration类列表,由@EnableAutoConfiguration
注解中的exclude/excludeName
参数筛选一遍,再由AutoConfigurationImportFilter
类所有实例筛选一遍,得到最终的用于Import的configuration和exclusion。
另外,还有一个注解@AutoConfigurationPackage
, @AutoConfigurationPackage注解的作用是将 添加该注解的类所在的package 作为 自动配置package 进行管理,还有@AutoConfigurationPackage注解的主要作用就是将主程序类所在包及所有子包下的组件到扫描到spring容器中。
因此 在定义项目包结构时,要求定义的包结构非常规范,项目主程序启动类要定义在最外层的根目录位置,然后在根目录位置内部建立子包和类进行业务开发,这样才能够保证定义的类能够被组件扫描器扫描
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!