程序入口(SpringApplication)
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
监听器的过程
-->程序启动
-->调用getRunListeners(args)获取SpringApplicationRunListeners实例
-->getSpringFactoriesInstances()获取Spring工厂实例
-->loadFactoryNames()通过classLoader加载工厂实例
-->loadSpringFactories() 循环加载/META-INF/spring.factories中的类,组成集合返回
-->createSpringFactoriesInstances()根据加载文件返回的类名创建工厂实例,反射
-->listeners.starting()启动监听器
-->multicastEvent(ApplicationEvent event)组播ApplicationEvent事件
-->getApplicationListeners()判断监听器类型是否与当前监听器类型相同
-->retrieveApplicationListeners(eventType, sourceType, retriever)检索给定事件和源类型的应用程序监听器。
-->supportsEvent(listener, eventType, sourceType)确定给定的监听器是否支持给定的事件。
-->GenericApplicationListenerAdapter(ApplicationListener<?> delegate)为给定的委托创建一个新的GenericApplicationListener。
-->resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener)发布事件监听
-->supportsEventType(eventType)从指定类型解析事件
-->结束
断点跟踪
1.获取监听
private SpringApplicationRunListeners getRunListeners(String[] args) {
//定义class数组
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
//创建SpringApplicationRunListeners 对象
return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
SpringApplicationRunListener.class, types, this, args));
}
2.获取spring工厂实例
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
// 类加载器
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
// 这个返回值是 META-INF/spring.factories 中定义的 父节点
// names的返回值 传送门7号
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//内部循环初始化 names的构造器
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
3.加载工厂
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}