Spring Boot自动装配原理

本文主要介绍

1. Spring Boot是如何完成自动装配的

2.Spring Boot核心启动类方法的执行流程

1. Spring Boot是如何完成自动装配的

概念

  • 自动装配:根据我们在POM中添加的jar依赖,Spring Boot会自动将一些配置类的bean注入到IOC容器中,在项目中,我们可以直接通过 @Autowired,@resourecs就可以直接使用

Spring Boot主程序类会使用@SpringBootApplication进行标注

 

 

如图可见@SpringBootApplication为组合注解

层层剖析后,本质将主程序类定义为@Configuration配置类,@ComponentScan定义包扫描(默认为主程序类所在包路径);以及向容器中导入组件类 AutoConfigurationImportSelector.class及 AutoConfigurationPackages.Registrar.class

1. 在AutoConfigurationImportSelector类的内部类AutoConfigurationGroup中定义了process()及selectImports(),在这两个方法中,将会

A.从spring.factories配置文件中加载自动配置类(所有META-INF下名字为spring.factories的配置中key为EnableAutoConfiguration全路径类名)

B. 加载的自动配置类中排除掉不需要自动配置的类;比如: @EnableAutoConfiguration 注解的 exclude 属性指定的,配置类中有些有标准是否配置的条件注解,不满足@ConditionalOnClass , @ConditionalOnBean 和 @ConditionalOnWebApplication 的条件也过滤掉;等

C. @Order注解的自动配置类进行排序

D.将符合条件的类信息存放到集合中

在Spring Boot的核心run方法中,在初始化了Spring上下文对象后,刷新上下文时 ,会调用SpringIOC的核心方法:refresh方法,refresh在调用invokeBeanFactoryPostProcessors即BeanFactory 的后处理器方法中,在解析BeanDefiniction时最终会调用到AutoConfigurationImportSelector类的内部类AutoConfigurationGroup中定义了process()及selectImports()方法.  将最后筛选出的自动配置类导入IOC容器中;从而实现自动装配

2.Spring Boot核心启动类方法的执行流程

 Spring Boot主程序会调用SpringApplication的run方法,传入主方法类信息及主函数参数信息

SpringApplication.run(MyTestApplication.class, args);

 在run方法的重载方法中

会初始化SpringApplication以及调用run方法

new SpringApplication(primarySources).run(args)

在SpringApplication的初始化方法中推断应用类型,初始化spring.factories中已配置的ApplicationContextInitializer及 ApplicationListener;根据方法调用栈,推断出 main 方法的类名

在run方法中运行spring应用,并刷新一个新的 ApplicationContext(Spring的上下文)即:ConfigurableApplicationContext对象

 依次完成获取并启动监听器,构建应用上下文环境(args),初始化应用上下文,刷新上下文对象等从而启动项目;

public ConfigurableApplicationContext run(String... args) {
   //记录程序运行时间
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   // ConfigurableApplicationContext Spring 的上下文
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
   //【1、获取并启动监听器】
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      //【2、构造应用上下文环境】
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
      //处理需要忽略的Bean
      configureIgnoreBeanInfo(environment);
      //打印banner
      Banner printedBanner = printBanner(environment);
      ///【3、初始化应用上下文】 //org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
      context = createApplicationContext();
      //实例化SpringBootExceptionReporter.class,用来支持报告关于启动的错误
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      //【4、刷新应用上下文前的准备阶段】
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      //【5、刷新应用上下文】
      refreshContext(context);
      //【6、刷新应用上下文后的扩展接口】
      afterRefresh(context, applicationArguments);
      //时间记录停止
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      //发布容器启动完成事件
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }

   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

在刷新应用上下文时,会调用Spring IOC容器的核心方法refresh进行对象创建等操作,而在refresh中在调用invokeBeanFactoryPostProcessors(beanFactory)即BeanFactory 的后处理器方法中:

1. 解析ComponsentScan 获取到要解析的包路径(配置未指定 basePackages、value
)扫描路径时,默认为注解所在类,会将主方法对应的包下所有的@Componsent注解的类信息封装到BeanDefiniction中,存放到beanDefinitionMap(IOC容器中) 

2. 调用AutoConfigurationImportSelector 内部类 AutoConfigurationGroup的 process() 及 selectImports()方法.从所有META-INF下的spring.factories文件中根据key为EnableAutoConfiguration全路径类名的类信息。进行必要过滤后,最终过滤后的类信息生成对应的信息放入IOC容器中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值