SpringBoot&Spring

By youfang

SpringBoot&Spring

SpringApplication的run方法

  1. 首先会创建StopWatch来统计启动耗时。

  2. 获取所有的SpringApplicationRunListeners(默认有一个事件发布的Listener):—> getSpringFactoriesInstances来实例化SpringFactoriesLoader#loadSpringFactories META-INF/spring.factories

  3. prepareEnvironment根据启动参数来准备环境

  4. printBanner打印Banner

  5. createApplicationContext创建ApplicationContext,根据webApplicationType创建servlet/reactive。

    servlet:AnnotationConfigServletWebServerApplicationContext构建时注册5个默认处理器

    默认:AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner

    同时创建:DefaultListableBeanFactory

  6. prepareContext准备上下文,springboot中,在这里注册一个application启动类。 这里通过BeanDefinitionLoader去注册一些核心的BenDefinition.

  7. refreshContext刷新Context (核心)

    refreshContext(context);

    1. prepareRefresh()//切换到活跃,初始化PropertySources 等处理
    2. obtainFreshBeanFactory()//获取BeanFactory -> XML解析 -> 封装BeanDefinition
    3. prepareBeanFactory(beanFactory)//准备BeanFactory 为BeanFactory配置ClassLoader还有添加一些后处理器(ApplicationContextAwareProcessor等)
    4. postProcessBeanFactory(beanFactory)//默认没有实现,留给子类实现 这时候默认的bean definitions已经加载,但是还没有实例化
    5. invokeBeanFactoryPostProcessors(beanFactory)//调用 Bean Factory 后处理器 ConfigurationClassBeanDefinitionReader.loadBeanDefinitions() 扫描classpath解析出所有的BeanDefinition
    6. registerBeanPostProcessors(beanFactory)//注册所有的BeanPostProcessor
    7. initMessageSource()//初始化MessageSource
    8. initApplicationEventMulticaster();//初始化一个事件管理器(applicationEventMulticaster)(springboot的事件发布就是通过这个来实现的)
    9. onRefresh()//由子类来处理,springboot会在这里启动tomcat
    10. registerListeners()//注册ApplicationListener来监听ApplicationEvent
    11. finishBeanFactoryInitialization(beanFactory)//实例化所有剩余的(非延迟初始化)单例。单例、非抽象、非懒加载
    12. finishRefresh()//清除缓存,初始化生命周期处理器,发布ContextRefresh事件
  8. afterRefresh Context刷新后

  9. 告诉listeners started(context)

  10. 获取实现了ApplicationRunner和CommandLineRunner 的Bean来运行

  11. 告诉listeners running(context)

实例化过程

  1. 通过:FactoryMethod,有参构造,无参构造 来实例化,这时候属性为空。populateBean的时候来完成属性的注入。
  2. Autowired注解收集:applyMergedBeanDefinitionPostProcessor。
    1. AutoWiredAnnotationBeanPostProcessor(@Autowired、@Value)
    2. CommonAnnotationBeanPostProcessor(@Resource、@PostConstruct、@PreDestroy)

      收集为 InjectionMetaData : 用于管理注入元数据的内部类。不用于直接应用。

      inject() 方法会触发当前依赖注入属性的getBean。

  3. 依赖注入完成后,属性就有值了。

ConfigurationClassPostProcessor

收集(@Component @ComponentScan @Import @ImportSource @Configuration @Bean @PropertySources )

7.1 Xml解析和BeanDefinition封装,在步骤7中

obtainFreshBeanFactory方法

refreshBeanFactory() -> AbstractRefreshableApplicationContext#loadBeanDefinitions() 来解析成BeanDefinition

  1. XmlBeanDefinitionReader 来读取XML配置的Bean
  2. AnnotatedBeanDefinitionReader 来读取注解配置的Bean

BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 来获取BeanFactory

postProcessBeanDefinitionRegistry() 提供了BeanDefinitionRegistry来注册、移除、获取 BD

BeanDefinition

  1. id Bean的唯一标识
  2. name 为id创建一个或多个别名
  3. beanClass bean的Class
  4. scope singleton或者是prototype
  5. primary是否是主要的
  6. parent 子类Bean定义它所引用的父类Bean
  7. lazy-init 是否懒初始化,true:BeanFactory启动时,false:Bean请求时
  8. autowireMode Bean自动装载方式。no、byName、byType、Constructor
  9. dependsOn Bean依赖的对象,会在之前创建好这些对象
  10. initMethod 初始化方法
  11. destroyMethod 销毁方法
  12. factoryMethod与factoryBean 创建Bean的工厂方法与工厂类
  13. MutablePropertyValues

MutablePropertyValues类,List 包含k-v XML解析的时候会解析属性配置:

1
2
3
4
5
6
7
8
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>

内置Processor (AnnotatedBeanDefinitionReader)

1
2
3
4
5
6
0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"///用来解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"//用来解析@Autowired和@Value、@Inject注解
2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"//用来处理@PostConstruct、@PreDestroy和@Resource注解
3 = "org.springframework.context.event.internalEventListenerProcessor"//用来处理@EventListener事件监听注解
4 = "org.springframework.context.event.internalEventListenerFactory"//注册事件监听器工厂
5 = "application"

后处理器

  • 容器后处理器:BeanFactoryPostProcessor refreshContext()时执行一次
  • Bean后处理器:BeanPostProcessor initializeBean()的时候穿插执行

BeanPostProcessor:可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:

1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法

InitializingBean
ApplicationContextAware
BeanNameAware

循环依赖

前提:单例的、允许循环依赖的、在创建中的 允许Bean提前暴露。

  1. 通过addSingletonFactory来建立beanName 与 ObjectFactory 的映射关系(这里就是三级缓存)。
  2. getSingleton() 方法会从这里来创建对象。 一级缓存、二级缓存、三级缓存
  3. ObjectFactory 的 getObject() 方法来获取对象。

    二级缓存:不会走getEarlyBeanReference循环所有的BeanPostProcessor来拿对象。

三级缓存
ObjectFactory.

getEarlyBeanReference->wrapIfNecessary

正常情况:是在initializeBean中 - 初始化之后的后置处理器(AbstractAutoProxyCreator)中完成代理

只能存在单例,Prototype直接报错

depends on 优先getBean促使实例化

@Bean BeanDefinition中的FactoryMethod。

MergedBeanDefinitionPostProcessor

允许后处理器修改合并的 bean 定义。

doCreateBean中调用postProcessMergedBeanDefinition

//在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用

//这个算是将merged BeanDefinition暴露出来的一个回调

BeanDefinitionHolder的属性

  • BeanDefinition beanDefinition
  • String beanName
  • String[] aliases