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以及是否配置了符合这些条件注解的配置来进行装载的。

 

  • @SpringBootApplication是一个复合注解 ==> @SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。

 

  • @SpringBootConfiguration,就是一个配置类,@Configuration是底层的核心注解,作用和spring配置文件中往spring容器中注入对象(<bean>),只是springboot封装了Configuration, 叫成了SpringBootConfiguration。
  • @EnableAutoConfiguration是由@AutoConfigurationPackage ,@Import({AutoConfigurationImportSelector.class})两个注解组成
    • @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}) 配合使用,就是为了扫描和启动类同一级包名或包名下面所有的组件。

 

posted @ 2024-04-28 15:53  学Java的`Bei  阅读(9)  评论(0编辑  收藏  举报