• Spring IoC源码:finishRefresh 完成刷新详解


    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);
    
    				// 注册执行,BeanFactoryPostProcessor
    				invokeBeanFactoryPostProcessors(beanFactory);
    
    				// 注册创建BeanPostProcessor
    				registerBeanPostProcessors(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.
    				//实例化剩下非懒加载的Bean
    				finishBeanFactoryInitialization(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();
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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)) {
    			//获取或创建LifecycleProcessor
    			this.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() + "]");
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    方法3:onRefresh

    	public void onRefresh() {
    		startBeans(true);
    		this.running = true;
    	}
    
    • 1
    • 2
    • 3
    • 4
    private void startBeans(boolean autoStartupOnly) {
    		//获取Lifecycle类型的bean集合
    		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    		Map<Integer, LifecycleGroup> phases = new HashMap<>();
    		lifecycleBeans.forEach((beanName, bean) -> {
    			//autoStartupOnly 为true时,代表是容器自动启动调用,这时只有SmartLifecycle 类型且isAutoStartup为TRUE才会调用
    			//如果autoStartupOnly 为false,代表是手动调用,会调用所有的Lifecycle
    			if (!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<Integer> keys = new ArrayList<>(phases.keySet());
    			//排序
    			Collections.sort(keys);
    			//遍历调用
    			for (Integer key : keys) {
    				phases.get(key).start();
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    方法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 initialized
    		if (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);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    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);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    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);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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;
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    总结

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

  • 相关阅读:
    电子行业MES管理系统需求分析
    TypeScript算法题实战——字符串篇(字符串的反转、旋转、查询、KMP算法)
    FastDFS小文件存储原理
    HJ16 购物单
    (一)什么是消息中间件
    Codeforces Round #803 (Div. 2)(A-D)
    牛客刷题<二>异步复位的串联T触发器
    算法金 | 再见!!!梯度下降(多图)
    JAVA中简单的for循环竟有这么多坑,但愿你没踩过
    【C&C++编码规范】
  • 原文地址:https://blog.csdn.net/weixin_45031612/article/details/128193344