Spring源码-IOC容器初始化过程【2】
实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1
- Spring源码-IOC容器简介【1】
- Spring源码-IOC容器初始化过程【2】
- Spring源码-Xml Bean解析注册过程【3】
- Spring源码-自定义IOC容器及Bean解析注册【4】
- Spring源码-Bean实例化过程【5】
- Spring源码-Spring是如何解决Bean循环依赖的【6】
- Spring源码-循环依赖-用实例证明去掉二级缓存会出现什么问题【7】
- Spring源码-AOP是如何实现代理的【8】
容器的初始化过程主要通过AbstractApplicationContext的refresh()方法来完成,其主要步骤如下
AbstractApplicationContext#refresh()方法
refresh方法
/** * refresh方法的主要作用是:在创建IoC容器前,如果已经有容器存在,需要把已有的容器销毁和关闭, * 以保证在refresh方法之后使用的是新创建的IoC容器。 * 它类似于对IoC容器的重启,在新创建的容器中对容器进行初始化,对Bean配置资源进行载入。 */ @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1、准备刷新,获取当前时间,给容器设置同步表识 prepareRefresh(); // 2、子类刷新并初始化BeanFactory,在这一步生成beanFactory实例(DefaultListableBeanFactory), // 在这里完成BeanDefinition的加载(loadBeanDefinitions) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3、初始化beanFactory,设置容器特性,例如类加载器、事件处理器等 prepareBeanFactory(beanFactory); try { // 4、空方法,bean实例化之前执行。容器子类可以对beanFactory做一些操作 postProcessBeanFactory(beanFactory); // 5、bean实例化之前执行。用户可以继承BeanFactoryPostProcessors接口,在这一步对beanFactory做一些操作 invokeBeanFactoryPostProcessors(beanFactory); // 6、BeanPostProcessors是bean的后置处理器,用于监听容器触发的事件。 // 在bean实例化之后,init-method方法前后执行 // 用户可以继承BeanPostProcessors接口,在这一步对bean方法进行修改,具体执行在step12之后,这一步只是先注册上 registerBeanPostProcessors(beanFactory); // 7、初始化信息源,和国际化相关 initMessageSource(); // 8、初始化事件传播器 initApplicationEventMulticaster(); // 9、空方法,容器子类可以在这一步进行操作 onRefresh(); // 10、为事件传播器,注册事件监听器 registerListeners(); // 11、【重要】实例化所有剩余的非懒加载单例bean,在这一步完成bean的实例化 finishBeanFactoryInitialization(beanFactory); // 12、初始化容器的生命周期事件处理器,并且发布容器的生命周期事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁bean destroyBeans(); // 取消刷新,重置active标示 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // 清空缓存 resetCommonCaches(); } } }
1、prepareRefresh方法
prepareRefresh方法
/** * 准备刷新上下文,设置启动日期和活动标志、属性源的初始化。 */ protected void prepareRefresh() { // 设置启动时间 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 初始化上下文环境中的任何占位符属性源(空方法,交给子类实现) initPropertySources(); // 创建并获取环境对象,验证所有标记为必需的属性是否可解析 // 参考 ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // 初始化earlyApplicationEvents,在multicaster可用后发布 this.earlyApplicationEvents = new LinkedHashSet<>(); }
2、obtainFreshBeanFactory方法:在这一步创建了beanFactory实例,并且进行了bean资源的加载
obtainFreshBeanFactory方法
/** * 初始化BeanFactory,在这一步完成了loadBeanDefinitions的加载 */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 抽象方法,交给子类实现。 // 子类刷新beanFactory,比如子类AbstractRefreshableApplicationContext会在refreshBeanFactory方法里createBeanFactory,并且执行loadBeanDefinitions加载资源配置。 // 而GenericApplicationContext只会对已经创建好的beanFactory实例设置一下id即可,loadBeanDefinitions放在了外部去做。 refreshBeanFactory(); // getBeanFactory也是抽象方法,由子类创建beanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
比如子类AbstractRefreshableApplicationContext对其实现的refreshBeanFactory、getBeanFactory方法如下
refreshBeanFactory方法
/** * 刷新BeanFactory,实现父类AbstractApplicationContext的抽象方法 */ @Override protected final void refreshBeanFactory() throws BeansException { // 如果已经存在BeanFactory,销毁容器里的bean,关闭BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 创建beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 对IOC容器进行定制化,如设置启动参数、开启注解对自动装配等 customizeBeanFactory(beanFactory); // 调用载入bean定义对方法,loadBeanDefinitions(beanFactory)在本类是个抽象方法,交给子类实现 loadBeanDefinitions(beanFactory); // 加锁,写的时候不允许读写 synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } @Override public final ConfigurableListableBeanFactory getBeanFactory() { // 加锁,读的时候不允许写 synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }
3、prepareBeanFactory方法:对beanFactory做一些初始化的工作,设置一些默认属性
prepareBeanFactory方法
/** * 为BeanFactory设置一些初始化的属性值,例如上下文的类加载器和后处理器。 */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 设置忽略的Aware接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
4、postProcessBeanFactory方法
查看代码
/** * 根据上下文的标准修改其内部bean工厂初始化。所有bean定义都已加载,但没有bean将被实例化。 * 这允许注册特殊的BeanPostProcessors等在某些ApplicationContext实现中。 */ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
比如子类AbstractRefreshableWebApplicationContext对其实现如下
查看代码
/** * 注册request/session作用域 */ @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 添加Servlet容器相关的后置处理器 beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
5、invokeBeanFactoryPostProcessors方法:在这一步对BeanDefinition进行增强(相关修改操作)
invokeBeanFactoryPostProcessors方法
/** * BeanFactoryPostProcessor是在spring容器加载了beanDefinition之后,在bean实例化之前执行的。 * 实现BeanFactoryPostProcessor接口,可以在bean实例化之前修改beanDefinition相关配置。 * 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。 */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 检测LoadTimeWeaver并准备编织(如果同时发现)(例如,通过ConfigurationClassPostProcessor注册的@Bean方法) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
6、registerBeanPostProcessors方法
查看代码
/** * BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。 */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
7、initMessageSource方法
查看代码
/** * Initialize the MessageSource. * Use parent's if none defined in this context. */ protected void initMessageSource() { // 这里获取的beanFactory和refresh里obtainFreshBeanFactory获取的是同一个, ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isDebugEnabled()) { logger.debug("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isDebugEnabled()) { logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME + "': using default [" + this.messageSource + "]"); } } }
8、initApplicationEventMulticaster方法
查看代码
/** * spring中是通过ApplicationListener及ApplicationEventMulticaster来进行事件驱动开发的,即实现观察者设计模式或发布-订阅模式。 * ApplicationListener监听容器中发布的事件,只要事件发生,就触发监听器的回调,来完成事件驱动开发。属于观察者设计模式中的Observer对象。 * ApplicationEventMulticaster用来通知所有的观察者对象,属于观察者设计模式中的Subject对象。 */ protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 判断容器中是否存在applicationEventMulticaster // 也就是自定义的事件监听多路广播器,必须实现ApplicationEventMulticaster接口 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { // 如果没有,则默认采用SimpleApplicationEventMulticaster this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
9、onRefresh方法
查看代码
/** * 模板方法,可以重写该方法以添加特定于上下文的刷新工作。 * 在初始化特殊bean时调用,然后实例化单例。 */ protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }
10、registerListeners方法
查看代码
/** * 添加实现ApplicationListener的bean作为监听器。 * 不会影响其他监听器,可以添加这些监听器而无需添加bean。 */ protected void registerListeners() { // 首先注册静态指定的监听器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 不要在这里初始化FactoryBean:我们需要保留所有常规Bean,未初始化以允许后处理器应用于它们! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 发布早期应用程序事件现在我们终于有了一个multicaster Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
11、 finishBeanFactoryInitialization 详情见Spring源码-IOC部分-Bean实例化过程【5】
查看代码
/** * 完成此上下文的bean工厂的初始化,初始化所有剩余的单例bean。 */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 1.初始化此上下文的转换服务 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 3.初始化LoadTimeWeaverAware Bean实例对象 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了 beanFactory.freezeConfiguration(); // 5.实例化所有剩余(非懒加载)单例对象 (这一步很重要,bean的实例化是从这里开始的) beanFactory.preInstantiateSingletons(); }
12、finishRefresh方法
查看代码
/** * 完成刷新工作 * 调用LifecycleProcessor的onRefresh方法并发布 */ protected void finishRefresh() { // 清除上下文级别的资源缓存(例如来自扫描的ASM元数据)。 clearResourceCaches(); // 为此上下文初始化lifecycle processor。 initLifecycleProcessor(); // 首先将刷新传播到lifecycle processor。 getLifecycleProcessor().onRefresh(); // 发布事件 publishEvent(new ContextRefreshedEvent(this)); // 如果active,请参与LiveBeansView MBean。 LiveBeansView.registerApplicationContext(this); }
参考资料:
《Spring5核心原理与30个类手写》作者 谭勇德
《Spring源码深度解析》作者 郝佳
《Spring技术内幕》作者 计文柯
本文来自博客园,作者:wzyy,转载请注明原文链接:https://www.cnblogs.com/wwzyy/p/15859427.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!