-
什么是自动装配?
-
在传统的Spring程序开发中,需要我们手动配置大量的bean,例如数据源,事务管理器,视图解析器等。这些配置过程繁琐而容易出错,加大了开发难度和成本。而Spring Boot的自动装配机制则能够自动完成这些配置过程,使得开发者可以更加专注于业务逻辑的实现。
-
Spring Boot的自动装配通过扫描应用程序的classpath和依赖关系,自动配置和装配Spring应用程序所需的各种组件,提高了开发效率、减少了出错的可能性,并提升了应用程序的可维护性和可扩展性。
-
-
自动装配原理
-
几个重要的概念:
- 自动装配启动过程:在Spring Boot启动过程中,会扫描应用程序的classpath以及依赖关系,根据条件注解的判断结果来决定是否需要进行自动配置。
- 条件注解(Conditional Annotation):Spring Boot使用条件注解来确定是否需要进行自动配置。条件注解基于条件评估,根据一定的条件来判断是否需要进行自动配置。常见的条件注解包括@ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty等。
- Spring Boot Starter依赖:Spring Boot提供了一系列的Starter依赖,每个Starter依赖都定义了一组常用的依赖库,例如spring-boot-starter-web、spring-boot-starter-data-jpa等。这些Starter依赖通过自动配置机制,将所需的组件进行自动装配。
- 自动配置类(Auto-Configuration Class):每个Starter依赖都包含一个或多个自动配置类,这些自动配置类使用条件注解来判断是否需要进行自动配置。自动配置类通常包含@Configuration注解,其中定义了各种bean的创建和配置。
- 自动配置的优先级:在多个自动配置类中,可能存在相同类型的bean的创建和配置。Spring Boot使用自动配置的优先级来决定哪个自动配置类的设置会生效。一般来说,后加载的配置类会覆盖前面的配置类。开发者也可以通过自定义配置来覆盖默认的自动配置。
- 自定义配置:如果应用程序需要对自动配置进行修改或扩展,可以提供自己的配置类。这样可以通过编写自定义的bean来替换或扩展自动配置中的默认行为。
-
总结:Spring Boot的自动装配通过条件注解、自动配置类和Starter依赖等机制,根据条件判断和优先级规则来自动配置和装配应用程序所需的组件。这种方式简化了配置过程,提高了开发效率,同时也保留了灵活性,允许开发者进行自定义配置。
-
具体解释:
-
在SpringBoot的启动类上的@SpringBootApplication注解,实现了自动装配,他是一个复合注解,点进去之后发现有以下注解:
@SpringBootConfiguration //springboot配置 @EnableAutoConfiguration //自动配置 @ComponentScan( //组件扫描 excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} )
-
组件扫描@ComponentScan
-
spring中的注解 ,它对应XML配置中的元素
-
作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中
-
-
springboot配置@SpringBootConfiguration
- 作用:SpringBoot的配置类,标注在类上,表示这是一个SpringBoot的配置类,点进去之后有一个注解 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件,再点进去有一个 @Component 注解,说明启动类本身是Spring中的一个组件,负责启动应用。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true; } @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true; }
- 最重要的是其中的@EnableAutoConfiguration:以前我们需要自己配置的东西,SpringBoot可以自动帮我们配置 ; @EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效,点进去
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
其中,@AutoConfigurationPackage: 自动配置包,点进去是@Import({AutoConfigurationPackages.Registrar.class})注解,Registrar.class作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
@Import({AutoConfigurationImportSelector.class}),给容器导入AutoConfigurationImportSelector.class组件,这个组件是自动配置导入选择器,其中有一个方法如下:protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).getCandidates(); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct."); return configurations; }
这个方法调用了ImportCandiates的load方法,再继续往下点就能看到了很多自动配置的文件,这就是自动配置根源所在。
-
-
总结:
- SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
- 将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作
- 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中
- 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件
- 有了自动配置类,免去了手动编写配置注入功能组件等的工作
-
启动类主要做了以下四件事情:
-
推断应用的类型是普通的项目还是Web项目
-
查找并加载所有可用初始化器 , 设置到initializers属性中
-
找出所有的应用程序监听器,设置到listeners属性中
-
推断并设置main方法的定义类,找到运行的主类
-