二,EventPublishingRunListener类源码学习

发布于:2025-02-10 ⋅ 阅读:(51) ⋅ 点赞:(0)

了解Spring的SPI机制

Java SPI
SPI 全称 Service Provider Interface ,是 Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件 。 SPI的作用就是为这些被扩展的API 寻找服务实现 。本质是通过基于接口的 编程+策略模式+配置文件 实现动态加载。可以实现 解耦 (接口和实现分离),提高框架的 可拓展性 (第三方可以自己实现,达到插拔式的效果)。

getRunListeners()方法

/**
	 * 获取SpringApplicationRunListeners实例,listeners属性为SpringApplicationRunListener集合
	 * @param args
	 * @return
	 */
	private SpringApplicationRunListeners getRunListeners(String[] args) {
		// 构造参数设置
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };

		// TODO 前面获取过org.springframework.context.ApplicationListener,这里是
		// 获取SpringApplicationRunListener.class工厂实例,转成集合,并设置初始化器到属性listeners中
		// org.springframework.boot.SpringApplicationRunListener= \
		/*
		 * 读取的时候会去重以及排序的
		 * spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories 1个
		 */
		return new SpringApplicationRunListeners(
				logger,
				getSpringFactoriesInstances(SpringApplicationRunListener.class,
						types,
						this,
						args));
	}

getSpringFactoriesInstances()

/**
	 * 获取指定class路径对应配置的类集合,比如org.springframework.context.ApplicationContextInitializer
	 * 
	 * SPI机制的实现
	 * 从配置文件中加载接口的实现类
	 */
	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {

		// 1.获取一个类加载器
		ClassLoader classLoader = getClassLoader();

		// 2.遍历jar包META-INF/spring.factories的资源文件开始读取喽
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

		// 3.创建Spring工厂实例
		// TODO parameterTypes为工厂创建的实例对应的构造方法的签名样子,比如几个参数,每个参数的类型
		// TODO args为对应的构造参数的具体值
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

		// 4.对Spring工厂实例排序(org.springframework.core.annotation.Order注解指定的顺序)
		AnnotationAwareOrderComparator.sort(instances);

		return instances;
	}

SpringApplicationRunListeners

class SpringApplicationRunListeners {

	private final Log log;

	private final List<SpringApplicationRunListener> listeners;

	SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
		this.log = log;
		this.listeners = new ArrayList<>(listeners);
	}

	//省略一下代码....

}

EventPublishingRunListener

/**
 *
 * 根据SpringBoot启动过程中不同阶段发布对应的事件
 */
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

	private final SpringApplication application;

	private final String[] args;

	private final SimpleApplicationEventMulticaster initialMulticaster;

	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		//事件发布是通过下面这个多播器来实现发布的
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}

}


网站公告

今日签到

点亮在社区的每一天
去签到