SpringBoot自动装配原理
个人理解,SpringBoot就是由Spring和SpringMVC整合而来。开箱即用、简化监控、简化配置、简化部署;约定大于配置;
boot脱离了传统Spring手动配置大量的bean,而SpringBoot自动装配改变了繁琐的局面。
Spring Boot 的自动配置基于条件注解和自动配置类,它能够根据应用程序的依赖和环境,自动决定应该应用哪些配置和装配哪些 Bean。这意味着开发者只需要添加相应的依赖,写少量的配置代码,Spring Boot 就能够为我们完成大部分的配置工作,极大地简化了开发流程。
自动装配原理:
SpringBoot启动时,依靠启动类的main()方法;而main()方法执行的是SpringApplication.run()方法,而SpringApplication.run()方法中会创建spring的容器,并且刷新容器。而在刷新容器的时候就会去解析启动类,然后就会去解析启动类上的@SpringBootApplication注解,而这个注解是个复合注解,这个注解中有一个@EnableAutoConfiguration注解,这个注解就是开启自动配置,这个注解中又有@Import注解引入了一个AutoConfigurationImportSelector这个类,这个类经过一些核心方法,然后去扫描我们所有jar包下的META-INF下的spring.factories文件,而从这个配置文件中取找key为EnableAutoConfiguration类的全路径的值下面的所有配置都加载,这些配置里面都是有条件注解的,然后这些条件注解会根据你当前的项目依赖的pom以及是否配置了符合这些条件注解的配置来进行装载的。
-
@AutoConfigurationPackage是由 @Import({Registrar.class})实现的,核心方法是registerBeanDefinitions(),就是为了获取启动类所在的包,为后面扫描组件做准备。
-
@Import({AutoConfigurationImportSelector.class}) 核心类是AutoConfigurationImportSelector。
-
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } else { // 获取@EnableAutoConfiguration标注类的元信息。(exclude,excludeName) AnnotationAttributes attributes = this.getAttributes(annotationMetadata); // 获取自动装配类的候选类名称。 List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); //去重,排除重复的configurations configurations = this.removeDuplicates(configurations); //获取自动装配组件的排除名单。 Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); //检查排除类是否合法 this.checkExcludedClasses(configurations, exclusions); //移除所有的排除名单 configurations.removeAll(exclusions); //进行过滤,autoConfigurationMetadata充当过滤条件。 configurations = this.getConfigurationClassFilter().filter(configurations); //自动装配的导入事件 this.fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); } }
-
@ComponentScan 组件扫描和 @Import({Registrar.class}) 配合使用,就是为了扫描和启动类同一级包名或包名下面所有的组件。