spring容器初始化过程

卖梨的 / 2023-08-28 / 原文

2023.8.27

1.最核心的是BeanFactory,java bean全在里面。

2.ApplicationContext是java对象管理的开端,其实现类很多

  spring boot 中使用的ApplicationContext -> AnnotationConfigApplicationContext -> 使用java配置来实现将javabean信息注入到容器

  spring中最常用的ApplicationContext -> ClassPathXmlApplicationContext -> 使用xml来将javabean信息注入到容器

这两个类都有继承自AbstractApplication 所有的spring对象初始化的时候都会调用这个通用的类 , 整个bean初始化,容器加载相关的逻辑都是在这里面的

3.要注意refresh()方法,完成了整个spring生命周期的初始化

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
        prepareRefresh();
        // 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 初始化beanfactory的各种属性
        prepareBeanFactory(beanFactory);
        try {
            // 模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
            //允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展prepareBeanFactory(beanFactory)的方法
            postProcessBeanFactory(beanFactory);
            // 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)
            invokeBeanFactoryPostProcessors(beanFactory);
            // 实例化和注册beanFactory中扩展了BeanPostProcessor的bean
            //例如:
            // AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
            // RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
            // CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
            registerBeanPostProcessors(beanFactory);
            // Initialize message source for this context.
            initMessageSource();
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
            // 模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
            onRefresh();
            // 注册监听器,广播early application events
            registerListeners();
            // 实例化所有剩余的(非懒加载)单例
            // 比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。
            // 实例化的过程各种BeanPostProcessor开始起作用。
            finishBeanFactoryInitialization(beanFactory);
            // refresh做完之后需要做的其他事情。
            // 清除上下文资源缓存(如扫描中的ASM元数据)
            // 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
            // 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
            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();
        }
    }
}

以上代码及注释来源  https://zhuanlan.zhihu.com/p/129367591

 

4.如何解决循环引用就很简单了 , 如果A依赖了B 并且B依赖了A , 当A初始化了B的时候, B初始化时将会从第三层引用中获取当前的提早曝光的类,从而实现了解决循环引用,并且spring的实现,还实现了多线程模式下也可以进行循环应用的逻辑
还没完,整个生命周期还没有彻底搞懂