程序入口(SpringApplication)
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
監聽器的過程
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());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
//從cache 實例的結果集 是Null 因爲當前的cache 是空的。
// cache 實現 new ConcurrentReferenceHashMap<>()
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
// urls 返回值 見傳送門2號
Enumeration<URL> urls = (classLoader != null ?
// 獲取 META-INF/spring.factories 中的資源
// FACTORIES_RESOURCE_LOCATION = META-INF/spring.factories
//classLoader 不是null 走getResources方法
//見傳送門1號
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
//循環處理urls中的元素
while (urls.hasMoreElements()) {
// 獲取元素
// 第一個文件url地址 傳送門3號
// 第二個文件url地址 傳送門3號
// 後續文件 同上
UrlResource resource = new UrlResource(url);
//解析文件 把文件內容變成配置屬性
// 傳送門4號
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
//循環解析並把結果放到result中
//傳送門5號
for (Map.Entry<?, ?> entry : properties.entrySet()) {
List<String> factoryClassNames = Arrays.asList(
StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));
result.addAll((String) entry.getKey(), factoryClassNames);
}
}
//緩存類加載器和文件解析的結果集
// map.put
cache.put(classLoader, result);
// 結果 爲13條
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
4.創建Spring工廠實例
private <T> List<T> createSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
Set<String> names) {
List<T> instances = new ArrayList<>(names.size());
// 循環處理names的值
for (String name : names) {
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass
.getDeclaredConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
}
catch (Throwable ex) {
throw new IllegalArgumentException(
"Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
throws ClassNotFoundException, LinkageError {
Assert.notNull(name, "Name must not be null");
Class<?> clazz = resolvePrimitiveClassName(name);
if (clazz == null) {
// 緩存值爲空 無緩存 new HashMap<>(64);
clazz = commonClassCache.get(name);
}
if (clazz != null) {
return clazz;
}
//3個if判斷
。。。。。。
//通過加載器加載name值對應的類
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = getDefaultClassLoader();
}
try {
//反射
return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
}
catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
if (lastDotIndex != -1) {
String innerClassName =
name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
try {
return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
}
catch (ClassNotFoundException ex2) {
// Swallow - let original exception get through
}
}
throw ex;
}
}
5.加載監聽器類
listeners.starting();斷點進入
獲取EventPublishingRunListener調用構造方法
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
// 給initialMulticaster 添加listener
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
6.啓動監聽
添加完監聽器之後,調用listeners.starting();
調用的是SpringApplicationRunListeners中的:
public void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
實現類調用EventPublishingRunListener的方法:
@Override
public void starting() {
//這個位置版本不同,寫法可能不一樣
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
在上面代碼中創建了一個ApplicationStartingEvent事件,將springapplication的this.application傳入,因此監聽的時候獲取的是SpringApplication實例。
執行SimpleApplicationEventMulticaster中的multicastEvent()方法:
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
執行SimpleApplicationEventMulticaster中的multicastEvent方法:
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//注意getApplicationListeners獲取對應的事件監聽器
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
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);
// Quick check for existing entry on ConcurrentHashMap...
// 快速檢查ConcurrentHashMap的現有條目。
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 =
retrieveApplicationListeners(eventType, sourceType, retriever);
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
//實際上檢索給定事件和源類型的應用程序監聽器是否匹配。
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
LinkedList<ApplicationListener<?>> allListeners = new LinkedList<>();
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
//這個listeners集合就是前文提到的從配置中過濾的10個監聽器類
//傳送門8號
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
//空值
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
//循環10個listeners調用supportsEvent方法
for (ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
省略。。。
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
//判斷listener的類型是否是GenericApplicationListener的一個實例
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener :
//適配模式
new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
調用newGenericApplicationListenerAdapter()
@SuppressWarnings("unchecked")
public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());
//判斷declaredEventType是否是ApplicationEvent事件
if (declaredEventType == null || declaredEventType.isAssignableFrom(
ResolvableType.forClass(ApplicationEvent.class))) {
//獲取傳入的監聽器類
Class<?> targetClass = AopUtils.getTargetClass(listener);
if (targetClass != listener.getClass()) {
declaredEventType = resolveDeclaredEventType(targetClass);
}
}
return declaredEventType;
}
調用resolveDeclaredEventType()方法獲取指定類繼承的父類或實現接口時傳遞的泛型對應的類型
@Nullable
static ResolvableType resolveDeclaredEventType(Class<?> listenerType) {
ResolvableType resolvableType = ResolvableType.forClass(listenerType).as(ApplicationListener.class);
return (resolvableType.hasGenerics() ? resolvableType.getGeneric() : null);
}
調用supportsEventType方法
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
if (this.delegate instanceof SmartApplicationListener) {
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
return (eventClass != null && ((SmartApplicationListener) this.delegate).
//調用supportsEventType(),實際是調用自己
supportsEventType(eventClass));
}
else {
return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
}
}
遍歷所有的監聽器,如果該監聽器監聽的事件爲傳遞的事件或傳遞事件的父類則表示該監聽器支持指定事件。
傳送門1號
// name = META-INF/spring.factories
public Enumeration<URL> getResources(String name) throws IOException {
@SuppressWarnings("unchecked")
Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
if (parent != null) {
tmp[0] = parent.getResources(name);
} else {
tmp[0] = getBootstrapResources(name);
}
tmp[1] = findResources(name);
return new CompoundEnumeration<>(tmp);
}
全路徑(本地路徑,根據配置不同路徑不同):
jar:file:/D:/maven/package/org/springframework/boot/spring-boot/2.0.2.RELEASE/spring-boot-2.0.2.RELEASE.jar!/META-INF/spring.factories
傳送門2號
傳送門3號
傳送門4號
value爲當前key對應的屬性值以逗號分隔字符串。
傳送門5號
傳送門6號
傳送門7號
names的值經過下面函數處理
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
傳送門8號