Spring IoC源码:finishRefresh 完成刷新详解
创始人
2024-03-21 01:13:15
0

文章目录

  • Spring源码系列:
  • 前言
  • 正文
    • 方法1:finishRefresh
    • 方法2:initLifecycleProcessor
    • 方法3:onRefresh
    • 方法4:publishEvent
    • 方法5:multicastEvent
    • 方法6:invokeListener
    • 方法7:doInvokeListener
  • 总结

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍
Spring IOC源码:核心流程介绍
Spring IOC源码:ApplicationContext刷新前准备工作
Spring IOC源码:obtainFreshBeanFactory 详解(上)
Spring IOC源码:obtainFreshBeanFactory 详解(中)
Spring IOC源码:obtainFreshBeanFactory 详解(下)
Spring IOC源码:<context:component-scan>源码详解
Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解
Spring IOC源码:registerBeanPostProcessors 详解
Spring IOC源码:实例化前的准备工作
Spring IOC源码:finishBeanFactoryInitialization详解
Spring IoC源码:getBean 详解
Spring IoC源码:createBean( 上)
Spring IoC源码:createBean( 中)
Spring IoC源码:createBean( 下)
Spring IoC源码:finishRefresh 完成刷新详解

前言

当完成Bean定义信息解析、Bean的创建、初始化流程之后,到最后一个方法finishRefresh完成上下文刷新。

正文

来到refresh()方法中的最后一个方法finishRefresh();

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 容器刷新前准备工作prepareRefresh();// Tell the subclass to refresh the internal bean factory.//创建Bean工厂,解析配置ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// bean工厂准备工作prepareBeanFactory(beanFactory);try {//拓展接口,留给子类进行实现拓展postProcessBeanFactory(beanFactory);// 注册执行,BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);// 注册创建BeanPostProcessorregisterBeanPostProcessors(beanFactory);// 这个方法主要作用就是使用国际化,定制不同的消息文本,比如定义了一个Person的Bean,它有name属性,我们需要在不同的国家展示对应国家所在语言名称,这时候就可以使用国际化了。initMessageSource();// Initialize event multicaster for this context.//初始化应用事件广播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.//拓展接口,留给子类进行实现拓展,springboot就对该方法进行了处理onRefresh();// Check for listener beans and register them.//将内部的、以及我们自定义的监听器添加到缓存中,为后续逻辑处理做准备。还有添加事件源到缓存中。registerListeners();// Instantiate all remaining (non-lazy-init) singletons.//实例化剩下非懒加载的BeanfinishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.//使用应用事件广播器推送上下文刷新完毕事件(ContextRefreshedEvent )到相应的监听器。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();}}}

finishRefresh(),见方法1详解

方法1:finishRefresh

	protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).//清除该资源加载器中的所有资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.//初始化LifecycleProcessor。initLifecycleProcessor();// Propagate refresh to lifecycle processor first.//调用LifecycleProcessor的onRefresh方法进行刷新getLifecycleProcessor().onRefresh();// 发布事件publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}

initLifecycleProcessor(),见方法2详解

getLifecycleProcessor().onRefresh(),见方法3详解

publishEvent(new ContextRefreshedEvent(this)),见方法4详解

方法2:initLifecycleProcessor

	protected void initLifecycleProcessor() {//获取BeanFactory工厂ConfigurableListableBeanFactory beanFactory = getBeanFactory();//判断是否存在名称为lifecycleProcessor的Bean或定义信息if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {//获取或创建LifecycleProcessorthis.lifecycleProcessor =beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}}else {//bean工厂中不存在该bean的信息,则创建一个默认的DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);this.lifecycleProcessor = defaultProcessor;//注册添加到一级缓存中beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);if (logger.isTraceEnabled()) {logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}

方法3:onRefresh

	public void onRefresh() {startBeans(true);this.running = true;}
private void startBeans(boolean autoStartupOnly) {//获取Lifecycle类型的bean集合Map lifecycleBeans = getLifecycleBeans();Map phases = new HashMap<>();lifecycleBeans.forEach((beanName, bean) -> {//autoStartupOnly 为true时,代表是容器自动启动调用,这时只有SmartLifecycle 类型且isAutoStartup为TRUE才会调用//如果autoStartupOnly 为false,代表是手动调用,会调用所有的Lifecycleif (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {//获取阶段值,即优先级值。如果有实现Phased接口,则通过getPhase方法返回数值,值越小则排序越前int phase = getPhase(bean);//判断容器中是否已存在,不存在则创建LifecycleGroup 类型对象LifecycleGroup group = phases.get(phase);if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);phases.put(phase, group);}group.add(beanName, bean);}});if (!phases.isEmpty()) {List keys = new ArrayList<>(phases.keySet());//排序Collections.sort(keys);//遍历调用for (Integer key : keys) {phases.get(key).start();}}}

方法4:publishEvent

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessary//判断事件是否继承了ApplicationEvent接口ApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {//将事件封装成PayloadApplicationEvent类型的事件applicationEvent = new PayloadApplicationEvent<>(this, event);//设置事件类型if (eventType == null) {eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {//使用多播器发布事件getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...//使用父上下文进行发布事件if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}

getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType),见方法5详解

方法5:multicastEvent

	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {//获取事件源类型ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));Executor executor = getTaskExecutor();//根据事件类型获取对应类型的监听器for (ApplicationListener listener : getApplicationListeners(event, type)) {//调用监听器的onApplicationEvent方法if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {invokeListener(listener, event);}}}

invokeListener(listener, event)),见方法6详解

方法6:invokeListener

	protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {//获取错误处理器ErrorHandler errorHandler = getErrorHandler();if (errorHandler != null) {try {//调用监听器处理方法doInvokeListener(listener, event);}catch (Throwable err) {errorHandler.handleError(err);}}else {doInvokeListener(listener, event);}}

doInvokeListener(listener, event),见方法7详解

方法7:doInvokeListener

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {try {//调用监听器的onApplicationEvent方法,并传入事件listener.onApplicationEvent(event);}catch (ClassCastException ex) {String msg = ex.getMessage();if (msg == null || matchesClassCastMessage(msg, event.getClass())) {// Possibly a lambda-defined listener which we could not resolve the generic event type for// -> let's suppress the exception and just log a debug message.Log logger = LogFactory.getLog(getClass());if (logger.isTraceEnabled()) {logger.trace("Non-matching event type for listener: " + listener, ex);}}else {throw ex;}}}

总结

Spring IOC中refresh()所有方法都讲解完了,这里面的内容非车多,花了不少时间在看,但是感觉还是比较粗糙,文章中有很多点理解得不是很到位,如果大家有更好的见解,欢迎指点评论。学习IOC过程是非常枯燥的,但是耐心去看真的能发现这个框架设计真的很厉害,拓展性做得很好,有很多地方值得我们在工作中进行参考开发。后续会发布Spring 系列的其它文章,如AOP,只有不断的学习,才能加深对Spring框架的理解。

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...