Spring Boot源码之旅四SpringApplication启动流程四

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

 

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

 

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

 

初始化基本流程

SimpleApplicationEventMulticaster的multicastEvent广播事件

其实这个就是观察者模式,发布订阅模式,或者说事件驱动模式,如果看过netty就知道他里面的处理器的方法就是事件驱动模式,有兴趣的话可以看下我的netty哈哈。废话不多说,我们继续,这里会先进行事件类型解析,解析成ResolvableType类型。

    	@Override
    	public void multicastEvent(ApplicationEvent event) {
    		multicastEvent(event, resolveDefaultEventType(event));
    	}

resolveDefaultEventType获取ResolvableType实例

    	private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
    		return ResolvableType.forInstance(event);
    	}

ResolvableType的forInstance创建ResolvableType实例

如果是ResolvableTypeProvider类型就会获取类型实例返回,否则会创建一个ResolvableType 对象,将事件类型封装进去。

    	public static ResolvableType forInstance(Object instance) {
    		Assert.notNull(instance, "Instance must not be null");
    		if (instance instanceof ResolvableTypeProvider) {
    			ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType();
    			if (type != null) {
    				return type;
    			}
    		}
    		return ResolvableType.forClass(instance.getClass());
    	}
    
    	public static ResolvableType forClass(@Nullable Class<?> clazz) {
    		return new ResolvableType(clazz);//创建一个,把clazz封装进去
    	}

开始广播

获取所有监听器,如果没有执行器就直接调用,有的话会开线程调用,最终都是invokeListener

    	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)) {
    			if (executor != null) {
    				executor.execute(() -> invokeListener(listener, event));
    			}
    			else {
    				invokeListener(listener, event);
    			}
    		}
    	}

AbstractApplicationEventMulticaster的getApplicationListeners获取所有支持该事件的监听器

现在有个启动事件,但是不一定所有监听器都要支持该事件,如果不支持表示对此事件不关心,那就不需要通知给他了,所以这里就是为了找出支持该事件的监听器集合,找出来之后还会给事件和监听器集合做映射,放入缓存中。

    protected Collection<ApplicationListener<?>> getApplicationListeners(
    			ApplicationEvent event, ResolvableType eventType) {
    
    		Object source = event.getSource();//获取事件源,就是事件是谁触发的
    		Class<?> sourceType = (source != null ? source.getClass() : null);//事件源类型
    		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);//封装事件类型和事件源类型
    
    		// 从缓存中获取
    		ListenerRetriever retriever = this.retrieverCache.get(cacheKey);//获取监听器检索其
    		if (retriever != null) {
    			return retriever.getApplicationListeners();//有就直接返回对应的监听器集合
    		}
    		//可以用缓存的情况
    		if (this.beanClassLoader == null ||
    				(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
    						(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
    			// Fully synchronized building and caching of a ListenerRetriever
    			synchronized (this.retrievalMutex) {
    				retriever = this.retrieverCache.get(cacheKey);
    				if (retriever != null) {//双重检测
    					return retriever.getApplicationListeners();
    				}
    				retriever = new ListenerRetriever(true);
    				Collection<ApplicationListener<?>> listeners =//获取支持该事件的监听器集合,并放入retriever中
    						retrieveApplicationListeners(eventType, sourceType, retriever);
    				this.retrieverCache.put(cacheKey, retriever);//将事件和监听器集合映射
    				return listeners;
    			}
    		}
    		else {//不用缓存的情况,每次都取一遍
    			// No ListenerRetriever caching -> no synchronization necessary
    			return retrieveApplicationListeners(eventType, sourceType, null);
    		}
    	}

ListenerRetriever

这个其实就是存监听器的,但是只是对某些事件支持的监听器集合,可以是实例,也可以是bean的名字。

getApplicationListeners直接获取监听器集合

直接获取就是将bean名字的集合里的bean都实例化,然后跟监听器合并,去重,最后返回。

    	public Collection<ApplicationListener<?>> getApplicationListeners() {
    			List<ApplicationListener<?>> allListeners = new ArrayList<>(//尝试将两个合起来
    					this.applicationListeners.size() + this.applicationListenerBeans.size());
    			allListeners.addAll(this.applicationListeners);
    			if (!this.applicationListenerBeans.isEmpty()) {
    				BeanFactory beanFactory = getBeanFactory();
    				for (String listenerBeanName : this.applicationListenerBeans) {//实例化bean并加入进去
    					try {//直接获取
    						ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
    						if (this.preFiltered || !allListeners.contains(listener)) {
    							allListeners.add(listener);//去重后添加进去
    						}
    					}
    					catch (NoSuchBeanDefinitionException ex) {
    					
    					}
    				}
    			}
    			if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
    				AnnotationAwareOrderComparator.sort(allListeners);
    			}
    			return allListeners;
    		}

AbstractApplicationEventMulticaster的retrieveApplicationListeners

这个就是根据监听器是否支持该事件,进行监听器的筛选,最后把支持的监听器集合返回。其实还会涉及到bean名字的集合,支持该事件的会直接获取,然后放进不同的集合里,最后都会讲所有支持的监听器全部返回。这里会把监听器集合也放在ListenerRetriever里,以便于做事件类型和监听器集合的映射缓存。

    private Collection<ApplicationListener<?>> retrieveApplicationListeners(
    			ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
    
    		List<ApplicationListener<?>> allListeners = new ArrayList<>();
    		Set<ApplicationListener<?>> listeners;
    		Set<String> listenerBeans;
    		synchronized (this.retrievalMutex) {//获取SimpleApplicationEventMulticaster添加监听器的时候就加入进去的监听器集合
    			listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
    			listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
    		}
    
    
    		for (ApplicationListener<?> listener : listeners) {//遍历所有的监听器,看监听器是否支持该事件
    			if (supportsEvent(listener, eventType, sourceType)) {
    				if (retriever != null) {
    					retriever.applicationListeners.add(listener);//支持就添加进去
    				}
    				allListeners.add(listener);//也添加到allListeners里
    			}
    		}
    
    
    		if (!listenerBeans.isEmpty()) {//如果有监听的bean的话,也要加进去
    			ConfigurableBeanFactory beanFactory = getBeanFactory();
    			for (String listenerBeanName : listenerBeans) {
    				try {
    					if (supportsEvent(beanFactory, listenerBeanName, eventType)) {//支持该事件的直接获取
    						ApplicationListener<?> listener =
    								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
    						if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
    							if (retriever != null) {
    								if (beanFactory.isSingleton(listenerBeanName)) {
    									retriever.applicationListeners.add(listener);
    								}
    								else {
    									retriever.applicationListenerBeans.add(listenerBeanName);
    								}
    							}
    							allListeners.add(listener);
    						}
    					}
    					else {//不支持就删除
    
    						Object listener = beanFactory.getSingleton(listenerBeanName);
    						if (retriever != null) {
    							retriever.applicationListeners.remove(listener);
    						}
    						allListeners.remove(listener);
    					}
    				}
    				catch (NoSuchBeanDefinitionException ex) {
    
    				}
    			}
    		}
    
    		AnnotationAwareOrderComparator.sort(allListeners);
    		if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
    			retriever.applicationListeners.clear();
    			retriever.applicationListeners.addAll(allListeners);//添加一遍,防止漏了
    		}
    		return allListeners;
    	}

还有个是否支持该事件没讲,后面讲吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值