通过这段代码作为分析的入口。以下分析都基于该示例,完整代码见:https://github.com/abelzha/spring-framework

public class InitMain {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfigInit.class);System.out.println(Arrays.asList(context.getBeanFactory().getBeanDefinitionNames()).toString().replaceAll(",", "\n"));Person person = context.getBean(Person.class);System.out.println(person.getName());context.close();}
}

1. IOC容器启动—Bean的初始化顺序

在Spring启动的时候会先创建容器、进行Bean的初始化。

1、根据配置类,创建容器,完成添加内置类的beanDefinitionMap

1、创建容器(AnnotationConfigApplicationContext)
容器的中的bean工厂:DefaultListableBeanFactory

2、初始配置信息设置,填充各种map、set.如下图所示

现在我们只关注一个map,它就是beanDefinitionMap。
将内置类的beanDefinition放入beanDefinitionMap,以下是该示例的默认添加的5个内置类

1    name:org.springframework.context.annotation.internalConfigurationAnnotationProcessor class:[org.springframework.context.annotation.ConfigurationClassPostProcessor]2  name:org.springframework.context.event.internalEventListenerFactoryclass:[org.springframework.context.event.DefaultEventListenerFactory]3   name:org.springframework.context.event.internalEventListenerProcessorclass:[org.springframework.context.event.EventListenerMethodProcessor]4    name:org.springframework.context.annotation.internalAutowiredAnnotationProcessor class:[org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor]5 name:org.springframework.context.annotation.internalCommonAnnotationProcessorclass:[org.springframework.context.annotation.CommonAnnotationBeanPostProcessor]

代码说明:

/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on* @param source the configuration source element (already extracted)* that this registration was triggered from. May be {@code null}.* @return a Set of BeanDefinitionHolders, containing all bean definitions* that have actually been registered by this call*/public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;}

2、添加传入的配置类的beanDefinitionMap

将AppConfigInit的beanDefinition放入beanDefinitionMap

至此,Spring启动只完成了beanFactory的实例化,添加内置bean和传入的配置类到beanDefinitionMap中,还没有开始扫描文件。

3、生成内置bean实例和业务bean实例

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.//允许在context子类中对bean工厂进行后处理。空方法postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.//调用工厂后置处理器,生成内置处理器的实例,并执行后置处理器的方法,从而通过扫描等获得其他业务bean的beanDefinition,并放入beanDefinitionMapinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.//注册beanPostProcessorsregisterBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}

1、调用工厂后置处理器,生成内置处理器的实例,并执行后置处理器的方法,从而通过扫描等获得其他业务bean的beanDefinition,并放入beanDefinitionMap

//调用工厂后置处理器,生成内置处理器的实例,并执行工厂后置处理器的方法,从而通过扫描等获得其他业务bean的beanDefinition,并放入beanDefinitionMap
invokeBeanFactoryPostProcessors(beanFactory);

2、从beanDefinitionNames的map中找出BeanPostProcessor,排序后,添加到bean工厂的beanPostProcessors Map中。
由registerBeanPostProcessors(beanFactory)来初始化BeanPostProcessor以及用户选择开启的功能(例如@EnableAspectJAutoProxy)而产生的BeanPostProcessor。

//注册beanPostProcessors
registerBeanPostProcessors(beanFactory);

1)先获取ioc容器中已经定义的需要创建对象的所有BeanPostProcessor
2)给容器中添加别的BeanPostProcessor(new BeanPostProcessorChecker)
3)优先注册实现了PriorityOrdered接口的BeanPostProcessor
4)再给容器中注册实现了Ordered接口的BeanPostProcessor
5)注册没有实现优先级接口的BeanPostProcessor
注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器beanFactory 。(List beanPostProcessors)
创建BeanPostProcessor对象的过程和创建普通业务bean使用的代码是一样的

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

3、实例化所有非懒加载的单实例,包括内置类、传入的配置类、普通业务类

 /*** Central method of this class: creates a bean instance,* populates the bean instance, applies post-processors, etc.* @see #doCreateBean*/@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// AOP的动态代理对象在此生成Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {// 创建bean实例Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}

(AOP动态代理对象在此生成,在bean实例对象创建之前)。

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

创建并注册Bean的过程,这个过程是一个通用的过程。
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法的功能)

1、创建bean的实例  createBeanInstance
2、MergedBeanDefinitionPostProcessor的后置处理器的处理
3、populateBean;给bean的填充各种属性
4、initializebean;初始化Bean;            1)invokeAwaremethods();处理bean Aware接口的方法回调           2)applyBeanPostProcessorsBeforeInitialization            3)invokeInitMethods();执行自定义的初始化方法            4)applyBeanPostProcessorsAfterInitialization

Spring启动—Bean的初始化顺序相关推荐

  1. Spring boot变量的初始化顺序

    起因是Spring建议"总是在您的bean中使用构造函数建立依赖注入.总是使用断言强制依赖",而且之前用@Autowired时idea总是给警告,于是全部改成了构造器注入,运行时发 ...

  2. Spring控制Bean加载顺序

    spring容器载入bean顺序是不确定的,spring框架没有约定特定顺序逻辑规范. 首先要了解depends-on或@DependsOn作用,是用来表示一个bean A的实例化依赖另一个bean ...

  3. Spring中bean的初始化和销毁几种实现方式详解

    关联博文:Spring中Bean的作用域与生命周期 Bean的生命周期 : 创建bean对象 – 属性赋值 – 初始化方法调用前的操作 – 初始化方法 – 初始化方法调用后的操作 – --- 销毁前操 ...

  4. 面试题------Spring中Bean的初始化以及销毁init-method、destory-method

    面试题------Spring中Bean的生命周期 通过Spring工厂,可以控制bean的生命周期. 在xml中配置Bean的初始化和销毁方法 通过init-method属性指定初始化后的调用方法. ...

  5. spring boot: Bean的初始化和销毁 (一般注入说明(三) AnnotationConfigApplicationContext容器 JSR250注解)...

    import org.springframework.context.annotation.AnnotationConfigApplicationContext; 使用AnnotationConfig ...

  6. Spring的Bean的初始化

    2019独角兽企业重金招聘Python工程师标准>>> ApplicationContext.xml的配置: <!-- UserDaoImpl的实例化 -->     & ...

  7. Spring中Bean初始化和销毁的多种方式

    Spring中Bean初始化和销毁的多种方式 一.Bean的多种初始化方式 1.PostConstruct注解 2.实现InitializingBean接口 3.声明init-method方法 二.B ...

  8. springboot---成员初始化顺序

    如果我们的类有如下成员变量: @Component public class A {@Autowiredpublic B b; // B is a beanpublic static C c; // ...

  9. 总结 Spring 注入 bean 的四种方式

    一提到 Spring,大家最先想到的是啥?是 AOP 和 IOC 的两大特性?是 Spring 中 Bean 的初始化流程?还是基于 Spring 的 Spring Cloud 全家桶呢? 今天我们就 ...

最新文章

  1. Centos 7.5安装配置MongoDB 4.0.5
  2. .NET MessageBox 网页弹出消息框
  3. python爬虫有什么用处-python为什么叫爬虫 python有什么优势
  4. group by 和 having(转载)
  5. vue项目搜索历史功能的实现
  6. ASP.NET中新建MVC项目并连接SqlServer数据库实现增删改查
  7. notepad++ 远程连接阿里云服务器
  8. [ST2017] Lab1: Triangle type and Junit test
  9. node.js——阿里企业级服务框架Egg搭建
  10. python api测试框架_python api 测试框架
  11. 浅析RTB和RTA(二)
  12. input输入框提示从数据库查出来的一堆数据
  13. 苹果有益让老iPhone变慢以迫使消费者购买新一代的iPhone?
  14. 小D课堂 - 新版本微服务springcloud+Docker教程_4-06 Feign核心源码解读和服务调用方式ribbon和Feign选择...
  15. win10系统dnf安装不上服务器,升级到Win10正式版后不能玩DNF如何解决?
  16. 加工中心计算机编程自学,自学加工中心编程(简单易学)图文讲解
  17. 整理好全球半导体公司,看看哪些你的上下游厂家
  18. 使用 Kind 在 5 分钟内快速部署一个 Kubernetes 高可用集群
  19. 互动派年会-comsol专题超强干货剖析
  20. Vue keep-alive组件缓存 基础用法

热门文章

  1. 卷积公式的理解,卷积其实就是叠加与衰减。
  2. Apache Bloodhound 0.5.3 发布,项目跟踪
  3. Mustache模板技术,一个比freemarker轻量级的模板引擎
  4. 为什么 TCP 会被 UDP 取代
  5. 塞尔达传说顺序_电子游戏《塞尔达传说》中的怪物如何结成历史小说
  6. 我们身边40岁的Android程序员的“晚年“
  7. HE: Flexibility and Efficiency of Use(提供灵活和高效的使用方式
  8. Unity-业余2D游戏制作笔记01-Dialogue System for Unity使用
  9. 将 uniqueidentifier 值转换为 char 时结果空间不足
  10. 用JAVA定义两个结构体_c语言struct结构体的定义和使用