spring容器初始化过程
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的实现,还实现了多线程模式下也可以进行循环应用的逻辑
还没完,整个生命周期还没有彻底搞懂