运行SpringApplication一

调用SpringApplication实例的run方法

org.springframework.boot.StringApplication

public ConfigurableApplicationContext run(String... args) {
	long startTime = System.nanoTime();
	DefaultBootstrapContext bootstrapContext = createBootstrapContext();
	ConfigurableApplicationContext context = null;
	configureHeadlessProperty();
	SpringApplicationRunListeners listeners = getRunListeners(args);
	listeners.starting(bootstrapContext, this.mainApplicationClass);
	try {
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
		configureIgnoreBeanInfo(environment);
		Banner printedBanner = printBanner(environment);
		context = createApplicationContext();
		context.setApplicationStartup(this.applicationStartup);
		prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
		refreshContext(context);
		afterRefresh(context, applicationArguments);
		Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
		if (this.logStartupInfo) {
			new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
		}
		listeners.started(context, timeTakenToStartup);
		callRunners(context, applicationArguments);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, listeners);
		throw new IllegalStateException(ex);
	}
	try {
		Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
		listeners.ready(context, timeTakenToReady);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, null);
		throw new IllegalStateException(ex);
	}
	return context;
}

记录开始时间

long startTime = System.nanoTime();

创建引导上下文

DefaultBootstrapContext bootstrapContext = createBootstrapContext();

— createBootstrapContext start

org.springframework.boot.StringApplication

private DefaultBootstrapContext createBootstrapContext() {
	DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
	this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
	return bootstrapContext;
}

— createBootstrapContext end
方法除了创建默认的上下文实例外,还会遍历引导注册器初始化器并调用其初始化方法

声明应用上下文

ConfigurableApplicationContext context = null;

配置Headless模式

configureHeadlessProperty();

— configureHeadlessProperty start

org.springframework.boot.StringApplication

private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";

private boolean headless = true;

private void configureHeadlessProperty() {
	System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
			System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}

— configureHeadlessProperty end
Headless模式是缺少显示设备,键盘或鼠标时的系统配置,通过系统参数java.awt.headless设定
缺省时默认启用

获取运行监听器

SpringApplicationRunListeners listeners = getRunListeners(args);

— getRunListeners start

org.springframework.boot.StringApplication

private SpringApplicationRunListeners getRunListeners(String[] args) {
	Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
	return new SpringApplicationRunListeners(logger,
			getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
			this.applicationStartup);
}

创建参数类型数组

Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };

创建并返回运行监听器集合实例

return new SpringApplicationRunListeners(logger,
		getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
		this.applicationStartup);
org.springframework.boot.StringApplication

private static final Log logger = LogFactory.getLog(SpringApplication.class);

private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
获取org.springframework.boot.SpringApplicationRunListener实例
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)

得到唯一实例org.springframework.boot.context.event.EventPublishingRunListener
—— EventPublishingRunListener start

org.springframework.boot.context.event.EventPublishingRunListener

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);
	}
}
创建事件投掷器
this.initialMulticaster = new SimpleApplicationEventMulticaster();
遍历应用的监听器集合并添加至事件投掷器
for (ApplicationListener<?> listener : application.getListeners()) {
	this.initialMulticaster.addApplicationListener(listener);
}

——— addApplicationListener start

org.springframework.context.event.AbstractApplicationEventMulticaster

private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();

final Map<ListenerCacheKey, CachedListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
	synchronized (this.defaultRetriever) {
		// Explicitly remove target for a proxy, if registered already,
		// in order to avoid double invocations of the same listener.
		Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
		if (singletonTarget instanceof ApplicationListener) {
			this.defaultRetriever.applicationListeners.remove(singletonTarget);
		}
		this.defaultRetriever.applicationListeners.add(listener);
		this.retrieverCache.clear();
	}
}
获取代理的单一目标实例
Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);

———— getSingletonTarget start

org.springframework.aop.framework.AopProxyUtils

@Nullable
public static Object getSingletonTarget(Object candidate) {
	if (candidate instanceof Advised) {
		TargetSource targetSource = ((Advised) candidate).getTargetSource();
		if (targetSource instanceof SingletonTargetSource) {
			return ((SingletonTargetSource) targetSource).getTarget();
		}
	}
	return null;
}

———— getSingletonTarget end

判断为org.springframework.context.ApplicationListener后从默认检索器中移除
if (singletonTarget instanceof ApplicationListener) {
	this.defaultRetriever.applicationListeners.remove(singletonTarget);
}

将代理目标移除,避免监听器被二次调用

添加至默认检索器中
this.defaultRetriever.applicationListeners.add(listener);
清理检索器缓存
this.retrieverCache.clear();

——— addApplicationListener end
—— EventPublishingRunListener end

applicationStartup用于供核心容器及其基础设施组件使用,在应用程序启动期间标记步骤,并收集有关执行上下文或其处理时间的数据
org.springframework.core.metrics.ApplicationStartup

ApplicationStartup DEFAULT = new DefaultApplicationStartup();

SpringApplication实例初始化时创建org.springframework.core.metrics.ApplicationStartup接口默认实现类org.springframework.core.metrics.DefaultApplicationStartup的实例
DefaultApplicationStartup对接口方法均为空实现,并无逻辑

创建应用运行监听器集合实例

——— SpringApplicationRunListeners start

org.springframework.boot.SpringApplicationRunListeners

private final Log log;

private final List<SpringApplicationRunListener> listeners;

private final ApplicationStartup applicationStartup;

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

——— SpringApplicationRunListeners end
— getRunListeners end

启动运行监听器

listeners.starting(bootstrapContext, this.mainApplicationClass);

— starting start

org.springframework.boot.SpringApplicationRunListeners

void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainApplicationClass) {
	doWithListeners("spring.boot.application.starting", (listener) -> listener.starting(bootstrapContext),
			(step) -> {
				if (mainApplicationClass != null) {
					step.tag("mainApplicationClass", mainApplicationClass.getName());
				}
			});
}

—— doWithListeners start

org.springframework.boot.SpringApplicationRunListeners

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
		Consumer<StartupStep> stepAction) {
	StartupStep step = this.applicationStartup.start(stepName);
	this.listeners.forEach(listenerAction);
	if (stepAction != null) {
		stepAction.accept(step);
	}
	step.end();
}

创建启动步骤实例

StartupStep step = this.applicationStartup.start(stepName); // DefaultStartupStep

上文说过,DefaultStartupStep相关方法均为空实现,此处org.springframework.core.metrics.DefaultApplicationStartup$DefaultStartupStep的相关方法也是空实现

监听器处理

this.listeners.forEach(listenerAction);

listenerAction即上述lambda表达式(listener) -> listener.starting(bootstrapContext)
当下只有一个运行监听器org.springframework.boot.context.event.EventPublishingRunListener
——— starting start

org.springframework.boot.context.event.EventPublishingRunListener

@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
	this.initialMulticaster
			.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}
创建开始事件实例
new ApplicationStartingEvent(bootstrapContext, this.application, this.args)

———— ApplicationStartingEvent start

org.springframework.boot.context.event.ApplicationStartingEvent

private final ConfigurableBootstrapContext bootstrapContext;

public ApplicationStartingEvent(ConfigurableBootstrapContext bootstrapContext, SpringApplication application,
		String[] args) {
	super(application, args);
	this.bootstrapContext = bootstrapContext;
}
查看父类构造方法

————— SpringApplicationEvent start

org.springframework.boot.context.event.SpringApplicationEvent

private final String[] args;

public SpringApplicationEvent(SpringApplication application, String[] args) {
	super(application);
	this.args = args;
}
查看父类构造方法

—————— ApplicationEvent start

org.springframework.context.ApplicationEvent

private final long timestamp;

public ApplicationEvent(Object source) {
	super(source);
	this.timestamp = System.currentTimeMillis();
}
查看父类构造方法

——————— EventObject start

java.util.EventObject

protected transient Object source;

public EventObject(Object var1) {
	if (var1 == null) {
		throw new IllegalArgumentException("null source");
	} else {
		this.source = var1;
	}
}

——————— EventObject end
—————— ApplicationEvent end
————— SpringApplicationEvent end
———— ApplicationStartingEvent end

播送事件

———— multicastEvent start

org.springframework.context.event.SimpleApplicationEventMulticaster

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

@Override
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);
		}
	}
}
获取事件类型
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));

————— resolveDefaultEventType start

org.springframework.context.event.SimpleApplicationEventMulticaster

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

org.springframework.core.ResolvableType封装了java.lang.reflect.Type,提供了方法访问其超类、接口和泛型,并可将他们转为java.lang.Class
—————— forInstance start

org.springframework.core.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());
}

先判断当前实例类是否实现org.springframework.core.ResolvableTypeProvider接口,若实现了接口,可直接调用ResolvableType getResolvableType()方法返回类型,否则调用public static ResolvableType forClass(@Nullable Class<?> clazz)方法
——————— forClass start

org.springframework.core.ResolvableType

public static ResolvableType forClass(@Nullable Class<?> clazz) {
	return new ResolvableType(clazz);
}
查看构造方法
org.springframework.core.ResolvableType

/**
 * The underlying Java type being managed.
 */
private final Type type;

/**
 * Optional provider for the type.
 */
@Nullable
private final TypeProvider typeProvider;

/**
 * The {@code VariableResolver} to use or {@code null} if no resolver is available.
 */
@Nullable
private final VariableResolver variableResolver;

/**
 * The component type for an array or {@code null} if the type should be deduced.
 */
@Nullable
private final ResolvableType componentType;

@Nullable
private final Integer hash;

@Nullable
private Class<?> resolved;

private ResolvableType(@Nullable Class<?> clazz) {
	this.resolved = (clazz != null ? clazz : Object.class);
	this.type = this.resolved;
	this.typeProvider = null;
	this.variableResolver = null;
	this.componentType = null;
	this.hash = null;
}

——————— forClass end
—————— forInstance end
————— resolveDefaultEventType end

获取任务执行器
Executor executor = getTaskExecutor(); // null

————— getTaskExecutor start

org.springframework.context.event.AbstractApplicationEventMulticaster

@Nullable
private Executor taskExecutor;

@Nullable
protected Executor getTaskExecutor() {
	return this.taskExecutor;
}

————— getTaskExecutor end
当前未创建执行器

获取应用监听器集合并遍历
for (ApplicationListener<?> listener : getApplicationListeners(event, type))
获取监听器集合

————— getApplicationListeners start

org.springframework.context.event.SimpleApplicationEventMulticaster

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);

	// Potential new retriever to populate
	CachedListenerRetriever newRetriever = null;

	// Quick check for existing entry on ConcurrentHashMap
	CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey);
	if (existingRetriever == null) {
		// Caching a new ListenerRetriever if possible
		if (this.beanClassLoader == null ||
				(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
						(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
			newRetriever = new CachedListenerRetriever();
			existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);
			if (existingRetriever != null) {
				newRetriever = null;  // no need to populate it in retrieveApplicationListeners
			}
		}
	}

	if (existingRetriever != null) {
		Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
		if (result != null) {
			return result;
		}
		// If result is null, the existing retriever is not fully populated yet by another thread.
		// Proceed like caching wasn't possible for this current local attempt.
	}

	return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}
获取事件源
Object source = event.getSource(); // SpringApplication

由上文的构造方法可知,此处event即之前创建的org.springframework.boot.context.event.ApplicationStartingEvent实例
source即当前应用实例SpringApplication

获取源类型
Class<?> sourceType = (source != null ? source.getClass() : null);
创建缓存键
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

—————— ListenerCacheKey start

org.springframework.context.event.AbstractApplicationEventMulticaster$ListenerCacheKey

private final ResolvableType eventType;

@Nullable
private final Class<?> sourceType;

public ListenerCacheKey(ResolvableType eventType, @Nullable Class<?> sourceType) {
	Assert.notNull(eventType, "Event type must not be null");
	this.eventType = eventType;
	this.sourceType = sourceType;
}

—————— ListenerCacheKey end

声明新的监听器检索器
// Potential new retriever to populate
CachedListenerRetriever newRetriever = null;
获取已存在的监听器检索器
// Quick check for existing entry on ConcurrentHashMap
CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey); // null
判断是否已存在监听器检索器
if (existingRetriever == null)

初始没有监听器检索器,尝试创建检索器实例

判断是否创建新的检索器
// Caching a new ListenerRetriever if possible
if (this.beanClassLoader == null ||
		(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
				(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader))))

即判断event类和source类是否可被安全的缓存
—————— isCacheSafe start

org.springframework.util.ClassUtils

public static boolean isCacheSafe(Class<?> clazz, @Nullable ClassLoader classLoader) {
	Assert.notNull(clazz, "Class must not be null");
	try {
		ClassLoader target = clazz.getClassLoader();
		// Common cases
		if (target == classLoader || target == null) {
			return true;
		}
		if (classLoader == null) {
			return false;
		}
		// Check for match in ancestors -> positive
		ClassLoader current = classLoader;
		while (current != null) {
			current = current.getParent();
			if (current == target) {
				return true;
			}
		}
		// Check for match in children -> negative
		while (target != null) {
			target = target.getParent();
			if (target == classLoader) {
				return false;
			}
		}
	}
	catch (SecurityException ex) {
		// Fall through to loadable check below
	}

	// Fallback for ClassLoaders without parent/child relationship:
	// safe if same Class can be loaded from given ClassLoader
	return (classLoader != null && isLoadable(clazz, classLoader));
}
判断类不为空
Assert.notNull(clazz, "Class must not be null");
获取类的加载器
ClassLoader target = clazz.getClassLoader();

返回null为根类加载器,由底层语言编写,无法获得其引用

判断当前类的类加载器是否为给定类加载器或根类加载器
if (target == classLoader || target == null) {
	return true;
}
判断给定类加载器是否为空
if (classLoader == null) {
	return false;
}
判断给定类加载器是否为当前类的类加载器的子级
ClassLoader current = classLoader;
while (current != null) {
	current = current.getParent();
	if (current == target) {
		return true;
	}
}
判断给定类加载器是否为当前类的类加载器的父级
while (target != null) {
	target = target.getParent();
	if (target == classLoader) {
		return false;
	}
}
当给定类加载器和当前类的类加载器没有父子级关系时,判断是否可加载
return (classLoader != null && isLoadable(clazz, classLoader));

——————— isLoadable start

org.springframework.util.ClassUtils

private static boolean isLoadable(Class<?> clazz, ClassLoader classLoader) {
	try {
		return (clazz == classLoader.loadClass(clazz.getName()));
		// Else: different class with same name found
	}
	catch (ClassNotFoundException ex) {
		// No corresponding class found at all
		return false;
	}
}

——————— isLoadable end
总结,isCacheSafe方法基于双亲委派加载机制,判断给定的类加载器是否能加载到给定类

—————— isCacheSafe end
当前beanClassLoadernull

创建新检索器
newRetriever = new CachedListenerRetriever();
缓存检索器
existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever); // null
若当前键已缓存,置空
if (existingRetriever != null) {
	newRetriever = null;  // no need to populate it in retrieveApplicationListeners
}

检索器实例已存在时,当前实例冗余

若检索器已存在且检索器获取的的监听器集合不为空,直接返回
if (existingRetriever != null) {
	Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
	if (result != null) {
		return result;
	}
	// If result is null, the existing retriever is not fully populated yet by another thread.
	// Proceed like caching wasn't possible for this current local attempt.
}

—————— getApplicationListeners start

org.springframework.context.event.AbstractApplicationEventMulticaster$CachedListenerRetriever

@Nullable
public volatile Set<ApplicationListener<?>> applicationListeners;

@Nullable
public volatile Set<String> applicationListenerBeans;

@Nullable
public Collection<ApplicationListener<?>> getApplicationListeners() {
	Set<ApplicationListener<?>> applicationListeners = this.applicationListeners;
	Set<String> applicationListenerBeans = this.applicationListenerBeans;
	if (applicationListeners == null || applicationListenerBeans == null) {
		// Not fully populated yet
		return null;
	}

	List<ApplicationListener<?>> allListeners = new ArrayList<>(
			applicationListeners.size() + applicationListenerBeans.size());
	allListeners.addAll(applicationListeners);
	if (!applicationListenerBeans.isEmpty()) {
		BeanFactory beanFactory = getBeanFactory();
		for (String listenerBeanName : applicationListenerBeans) {
			try {
				allListeners.add(beanFactory.getBean(listenerBeanName, ApplicationListener.class));
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Singleton listener instance (without backing bean definition) disappeared -
				// probably in the middle of the destruction phase
			}
		}
	}
	if (!applicationListenerBeans.isEmpty()) {
		AnnotationAwareOrderComparator.sort(allListeners);
	}
	return allListeners;
}
创建监听器集合
List<ApplicationListener<?>> allListeners = new ArrayList<>(
			applicationListeners.size() + applicationListenerBeans.size());
添加监听器实例
allListeners.addAll(applicationListeners);
监听器名称集合不为空时,遍历名称集合通过工厂实例获取监听器实例,添加至监听器实例集合
if (!applicationListenerBeans.isEmpty()) {
	BeanFactory beanFactory = getBeanFactory();
	for (String listenerBeanName : applicationListenerBeans) {
		try {
			allListeners.add(beanFactory.getBean(listenerBeanName, ApplicationListener.class));
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Singleton listener instance (without backing bean definition) disappeared -
			// probably in the middle of the destruction phase
		}
	}
}
监听器名称集合不为空时,将集合重新排序
if (!applicationListenerBeans.isEmpty()) {
	AnnotationAwareOrderComparator.sort(allListeners);
}

—————— getApplicationListeners end
此时无已存在的检索器,继续执行

检索并返回监听器集合
return retrieveApplicationListeners(eventType, sourceType, newRetriever);

—————— retrieveApplicationListeners start

org.springframework.context.event.AbstractApplicationEventMulticaster

private Collection<ApplicationListener<?>> retrieveApplicationListeners(
		ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {

	List<ApplicationListener<?>> allListeners = new ArrayList<>();
	Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);
	Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);

	Set<ApplicationListener<?>> listeners;
	Set<String> listenerBeans;
	synchronized (this.defaultRetriever) {
		listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
		listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
	}

	// Add programmatically registered listeners, including ones coming
	// from ApplicationListenerDetector (singleton beans and inner beans).
	for (ApplicationListener<?> listener : listeners) {
		if (supportsEvent(listener, eventType, sourceType)) {
			if (retriever != null) {
				filteredListeners.add(listener);
			}
			allListeners.add(listener);
		}
	}

	// Add listeners by bean name, potentially overlapping with programmatically
	// registered listeners above - but here potentially with additional metadata.
	if (!listenerBeans.isEmpty()) {
		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)) {
								filteredListeners.add(listener);
							}
							else {
								filteredListenerBeans.add(listenerBeanName);
							}
						}
						allListeners.add(listener);
					}
				}
				else {
					// Remove non-matching listeners that originally came from
					// ApplicationListenerDetector, possibly ruled out by additional
					// BeanDefinition metadata (e.g. factory method generics) above.
					Object listener = beanFactory.getSingleton(listenerBeanName);
					if (retriever != null) {
						filteredListeners.remove(listener);
					}
					allListeners.remove(listener);
				}
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Singleton listener instance (without backing bean definition) disappeared -
				// probably in the middle of the destruction phase
			}
		}
	}

	AnnotationAwareOrderComparator.sort(allListeners);
	if (retriever != null) {
		if (filteredListenerBeans.isEmpty()) {
			retriever.applicationListeners = new LinkedHashSet<>(allListeners);
			retriever.applicationListenerBeans = filteredListenerBeans;
		}
		else {
			retriever.applicationListeners = filteredListeners;
			retriever.applicationListenerBeans = filteredListenerBeans;
		}
	}
	return allListeners;
}
创建所有监听器集合
List<ApplicationListener<?>> allListeners = new ArrayList<>();
创建过滤后的监听器集合
Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);
创建过滤后的监听器bean名称集合
Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);
声明监听器集合
Set<ApplicationListener<?>> listeners;
声明监听器bean名称集合
Set<String> listenerBeans;
将默认检索器的监听器集合及监听器bean名称集合作为初始值
synchronized (this.defaultRetriever) {
	listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
	listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}

此处defaultRetriever于之前实例化org.springframework.boot.context.event.EventPublishingRunListener时,构造方法内赋值

遍历监听器集合,将支持事件的监听器加入集合
for (ApplicationListener<?> listener : listeners) {
	if (supportsEvent(listener, eventType, sourceType)) {
		if (retriever != null) {
			filteredListeners.add(listener);
		}
		allListeners.add(listener);
	}
}

——————— supportsEvent start

org.springframework.context.event.AbstractApplicationEventMulticaster

protected boolean supportsEvent(
		ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {

	GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
			(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
	return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}

——————— supportsEvent end
supportsEvent方法先根据监听器的类型将其转换为通用监听器或监听器代理,再调用统一的方法判断当前监听器是否同时支持指定的事件类型和源类型

判断监听器bean名称集合是否为空
if (!listenerBeans.isEmpty())

此时集合为空,后面再分析

监听器集合排序
AnnotationAwareOrderComparator.sort(allListeners);
若检索器不为空,设置检索器的监听器集合
if (retriever != null) {
	if (filteredListenerBeans.isEmpty()) {
		retriever.applicationListeners = new LinkedHashSet<>(allListeners);
		retriever.applicationListenerBeans = filteredListenerBeans;
	}
	else {
		retriever.applicationListeners = filteredListeners;
		retriever.applicationListenerBeans = filteredListenerBeans;
	}
}
返回监听器集合
return allListeners;

总结retrieveApplicationListeners方法
先筛选出符合给定事件类型和源类型的监听器
若指定检索器不为null,将这些监听器实例或bean名称赋值给指定检索器(作为缓存)
最后返回监听器实例集合
—————— retrieveApplicationListeners end
当前获取到符合的监听器共3
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.context.config.DelegatingApplicationListener
————— getApplicationListeners end

遍历监听器集合

————— for start

调用当前监听器
if (executor != null) {
	executor.execute(() -> invokeListener(listener, event));
}
else {
	invokeListener(listener, event);
}

—————— invokeListener start

org.springframework.context.event.SimpleApplicationEventMulticaster

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);
	}
}
获取错误处理器
ErrorHandler errorHandler = getErrorHandler();

———————— getErrorHandler start

org.springframework.context.event.SimpleApplicationEventMulticaster

@Nullable
private ErrorHandler errorHandler;

@Nullable
protected ErrorHandler getErrorHandler() {
	return this.errorHandler;
}

———————— getErrorHandler end
默认无错误处理器

执行监听器
doInvokeListener(listener, event);

——————— doInvokeListener start

org.springframework.context.event.SimpleApplicationEventMulticaster

@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
	try {
		listener.onApplicationEvent(event);
	}
	catch (ClassCastException ex) {
		String msg = ex.getMessage();
		if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
				(event instanceof PayloadApplicationEvent &&
						matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
			// Possibly a lambda-defined listener which we could not resolve the generic event type for
			// -> let's suppress the exception.
			Log loggerToUse = this.lazyLogger;
			if (loggerToUse == null) {
				loggerToUse = LogFactory.getLog(getClass());
				this.lazyLogger = loggerToUse;
			}
			if (loggerToUse.isTraceEnabled()) {
				loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
			}
		}
		else {
			throw ex;
		}
	}
}
调用监听器的事件方法
listener.onApplicationEvent(event);
首先是org.springframework.boot.context.logging.LoggingApplicationListener

———————— onApplicationEvent start

org.springframework.boot.context.logging.LoggingApplicationListener

@Override
public void onApplicationEvent(ApplicationEvent event) {
	if (event instanceof ApplicationStartingEvent) {
		onApplicationStartingEvent((ApplicationStartingEvent) event);
	}
	else if (event instanceof ApplicationEnvironmentPreparedEvent) {
		onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
	}
	else if (event instanceof ApplicationPreparedEvent) {
		onApplicationPreparedEvent((ApplicationPreparedEvent) event);
	}
	else if (event instanceof ContextClosedEvent
			&& ((ContextClosedEvent) event).getApplicationContext().getParent() == null) {
		onContextClosedEvent();
	}
	else if (event instanceof ApplicationFailedEvent) {
		onApplicationFailedEvent();
	}
}
匹配启动事件类型
if (event instanceof ApplicationStartingEvent) {
	onApplicationStartingEvent((ApplicationStartingEvent) event);
}

————————— onApplicationStartingEvent start

org.springframework.boot.context.logging.LoggingApplicationListener

private LoggingSystem loggingSystem;

private void onApplicationStartingEvent(ApplicationStartingEvent event) {
	this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
	this.loggingSystem.beforeInitialize();
}
获取日志系统实例
this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());

—————————— get start

org.springframework.boot.logging.LoggingSystem

public static LoggingSystem get(ClassLoader classLoader) {
	String loggingSystemClassName = System.getProperty(SYSTEM_PROPERTY);
	if (StringUtils.hasLength(loggingSystemClassName)) {
		if (NONE.equals(loggingSystemClassName)) {
			return new NoOpLoggingSystem();
		}
		return get(classLoader, loggingSystemClassName);
	}
	LoggingSystem loggingSystem = SYSTEM_FACTORY.getLoggingSystem(classLoader);
	Assert.state(loggingSystem != null, "No suitable logging system located");
	return loggingSystem;
}
获取日志系统类名称
String loggingSystemClassName = System.getProperty(SYSTEM_PROPERTY);
org.springframework.boot.logging.LoggingSystem

public static final String SYSTEM_PROPERTY = LoggingSystem.class.getName();

org.springframework.boot.logging.LoggingSystem

判断类名称是否为空
if (StringUtils.hasLength(loggingSystemClassName)) {
	if (NONE.equals(loggingSystemClassName)) {
		return new NoOpLoggingSystem();
	}
	return get(classLoader, loggingSystemClassName);
}

——————————— hasLength start

org.springframework.util.StringUtils

public static boolean hasLength(@Nullable String str) {
	return (str != null && !str.isEmpty());
}

——————————— hasLength end

org.springframework.boot.logging.LoggingSystem

public static final String NONE = "none";

若类名为"none",创建并返回内部的无日志系统实例org.springframework.boot.logging.LoggingSystem$NoOpLoggingSystem,即org.springframework.boot.logging.LoggingSystem的空实现类
若类名不为空且不为"none",根据类名实例化并返回
——————————— get start

org.springframework.boot.logging.LoggingSystem

private static LoggingSystem get(ClassLoader classLoader, String loggingSystemClassName) {
	try {
		Class<?> systemClass = ClassUtils.forName(loggingSystemClassName, classLoader);
		Constructor<?> constructor = systemClass.getDeclaredConstructor(ClassLoader.class);
		constructor.setAccessible(true);
		return (LoggingSystem) constructor.newInstance(classLoader);
	}
	catch (Exception ex) {
		throw new IllegalStateException(ex);
	}
}

——————————— get end
默认情况下类名为null,继续

通过系统工厂获取日志系统
LoggingSystem loggingSystem = SYSTEM_FACTORY.getLoggingSystem(classLoader);
org.springframework.boot.logging.LoggingSystem

private static final LoggingSystemFactory SYSTEM_FACTORY = LoggingSystemFactory.fromSpringFactories();
查看默认工厂实例

——————————— fromSpringFactories start

org.springframework.boot.logging.LoggingSystemFactory

static LoggingSystemFactory fromSpringFactories() {
	return new DelegatingLoggingSystemFactory(
			(classLoader) -> SpringFactoriesLoader.loadFactories(LoggingSystemFactory.class, classLoader));
}

———————————— DelegatingLoggingSystemFactory start

org.springframework.boot.logging.DelegatingLoggingSystemFactory

private final Function<ClassLoader, List<LoggingSystemFactory>> delegates;

DelegatingLoggingSystemFactory(Function<ClassLoader, List<LoggingSystemFactory>> delegates) {
	this.delegates = delegates;
}

———————————— DelegatingLoggingSystemFactory end
得知org.springframework.boot.logging.DelegatingLoggingSystemFactory为代理日志系统工厂,代理了获取日志系统工厂实例的方法
——————————— fromSpringFactories end

获取日志工厂实例

——————————— getLoggingSystem start

org.springframework.boot.logging.DelegatingLoggingSystemFactory

@Override
public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
	List<LoggingSystemFactory> delegates = (this.delegates != null) ? this.delegates.apply(classLoader) : null;
	if (delegates != null) {
		for (LoggingSystemFactory delegate : delegates) {
			LoggingSystem loggingSystem = delegate.getLoggingSystem(classLoader);
			if (loggingSystem != null) {
				return loggingSystem;
			}
		}
	}
	return null;
}
获取日志工厂实例集合
List<LoggingSystemFactory> delegates = (this.delegates != null) ? this.delegates.apply(classLoader) : null;

即运行lambda代码(classLoader) -> SpringFactoriesLoader.loadFactories(LoggingSystemFactory.class, classLoader)
———————————— loadFactories start

org.springframework.core.io.support.SpringFactoriesLoader

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
	Assert.notNull(factoryType, "'factoryType' must not be null");
	ClassLoader classLoaderToUse = classLoader;
	if (classLoaderToUse == null) {
		classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
	}
	List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
	if (logger.isTraceEnabled()) {
		logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
	}
	List<T> result = new ArrayList<>(factoryImplementationNames.size());
	for (String factoryImplementationName : factoryImplementationNames) {
		result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
	}
	AnnotationAwareOrderComparator.sort(result);
	return result;
}
读取工厂实现类名称集合
List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
创建工厂实例集合
List<T> result = new ArrayList<>(factoryImplementationNames.size());
遍历工厂实现类名称集合,实例化工厂并添加至集合
for (String factoryImplementationName : factoryImplementationNames) {
	result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
}

————————————— instantiateFactory start

org.springframework.core.io.support.SpringFactoriesLoader

@SuppressWarnings("unchecked")
private static <T> T instantiateFactory(String factoryImplementationName, Class<T> factoryType, ClassLoader classLoader) {
	try {
		Class<?> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
		if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
			throw new IllegalArgumentException(
					"Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
		}
		return (T) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();
	}
	catch (Throwable ex) {
		throw new IllegalArgumentException(
			"Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]",
			ex);
	}
}
获取可用构造器后传创建实例
return (T) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();

—————————————— accessibleConstructor start

org.springframework.util.ReflectionUtils

public static <T> Constructor<T> accessibleConstructor(Class<T> clazz, Class<?>... parameterTypes)
		throws NoSuchMethodException {

	Constructor<T> ctor = clazz.getDeclaredConstructor(parameterTypes);
	makeAccessible(ctor);
	return ctor;
}
获取构造器
Constructor<T> ctor = clazz.getDeclaredConstructor(parameterTypes);

这里获取为无参构造器

使构造器可用
makeAccessible(ctor);

——————————————— makeAccessible start

@SuppressWarnings("deprecation")  // on JDK 9
public static void makeAccessible(Constructor<?> ctor) {
	if ((!Modifier.isPublic(ctor.getModifiers()) ||
			!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) {
		ctor.setAccessible(true);
	}
}

——————————————— makeAccessible end

返回构造器
return ctor;

—————————————— accessibleConstructor end
————————————— instantiateFactory end

工厂实例集合排序
AnnotationAwareOrderComparator.sort(result);
返回工厂实例集合
return result;

———————————— loadFactories end
默认存在3个日志系统工厂实例
org.springframework.boot.logging.logback.LogbackLoggingSystem$Factory
org.springframework.boot.logging.log4j2.Log4J2LoggingSystem$Factory
org.springframework.boot.logging.java.JavaLoggingSystem$Factory

获取第一个日志工厂的日志系统实例
if (delegates != null) {
	for (LoggingSystemFactory delegate : delegates) {
		LoggingSystem loggingSystem = delegate.getLoggingSystem(classLoader);
		if (loggingSystem != null) {
			return loggingSystem;
		}
	}
}

返回org.springframework.boot.logging.logback.LogbackLoggingSystem实例
——————————— getLoggingSystem end

判断日志系统实例存在
Assert.state(loggingSystem != null, "No suitable logging system located");
返回日志系统实例
return loggingSystem;

—————————— get end

将日志系统实例进行预初始化操作
this.loggingSystem.beforeInitialize();

—————————— beforeInitialize start

org.springframework.boot.logging.logback.LogbackLoggingSystem

@Override
public void beforeInitialize() {
	LoggerContext loggerContext = getLoggerContext();
	if (isAlreadyInitialized(loggerContext)) {
		return;
	}
	super.beforeInitialize();
	loggerContext.getTurboFilterList().add(FILTER);
}
获取日志上下文
LoggerContext loggerContext = getLoggerContext();

——————————— getLoggerContext start

org.springframework.boot.logging.logback.LogbackLoggingSystem

private LoggerContext getLoggerContext() {
	ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
	Assert.isInstanceOf(LoggerContext.class, factory,
			() -> String.format(
					"LoggerFactory is not a Logback LoggerContext but Logback is on "
							+ "the classpath. Either remove Logback or the competing "
							+ "implementation (%s loaded from %s). If you are using "
							+ "WebLogic you will need to add 'org.slf4j' to "
							+ "prefer-application-packages in WEB-INF/weblogic.xml",
					factory.getClass(), getLocation(factory)));
	return (LoggerContext) factory;
}
获取日志工厂
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
获取单例装订器

———————————— getSingleton start

org.slf4j.impl.StaticLoggerBinder

/**
 * The unique instance of this class.
 */
private static StaticLoggerBinder SINGLETON = new StaticLoggerBinder();

static {
	SINGLETON.init();
}

public static StaticLoggerBinder getSingleton() {
	return SINGLETON;
}

查看org.slf4j.impl.StaticLoggerBinder构造方法
————————————— StaticLoggerBinder start

org.slf4j.impl.StaticLoggerBinder

private LoggerContext defaultLoggerContext = new LoggerContext();

private StaticLoggerBinder() {
	defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
}

查看ch.qos.logback.classic.LoggerContext构造方法
—————————————— LoggerContext start

ch.qos.logback.classic.LoggerContext

final Logger root;

private int size;

private Map<String, Logger> loggerCache;

private LoggerContextVO loggerContextRemoteView;

private List<String> frameworkPackages;

public LoggerContext() {
	super();
	this.loggerCache = new ConcurrentHashMap<String, Logger>();

	this.loggerContextRemoteView = new LoggerContextVO(this);
	this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);
	this.root.setLevel(Level.DEBUG);
	loggerCache.put(Logger.ROOT_LOGGER_NAME, root);
	initEvaluatorMap();
	size = 1;
	this.frameworkPackages = new ArrayList<String>();
}
父类构造方法
super();

——————————————— ContextBase start

ch.qos.logback.core.ContextBase

public ContextBase() {
	initCollisionMaps();
}
初始化碰撞集合

———————————————— initCollisionMaps start

ch.qos.logback.core.ContextBase

protected void initCollisionMaps() {
	putObject(FA_FILENAME_COLLISION_MAP, new HashMap<String, String>());
	putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
}
添加FileAppender碰撞集合
putObject(FA_FILENAME_COLLISION_MAP, new HashMap<String, String>());
ch.qos.logback.core.CoreConstants

/**
 * Key used to locate a collision map for FileAppender instances in context's object map.
 * 
 * The collision map consists of enties of the type (appender name, File option) 
 */
public static final String FA_FILENAME_COLLISION_MAP = "FA_FILENAME_COLLISION_MAP";

————————————————— putObject start

ch.qos.logback.core.ContextBase

Map<String, Object> objectMap = new HashMap<String, Object>();

public void putObject(String key, Object value) {
	objectMap.put(key, value);
}

————————————————— putObject end

添加RollingFileAppender碰撞集合
putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
ch.qos.logback.core.CoreConstants

/**
 * Key used to locate a collision map for RollingFileAppender instances in context's object map.
 * 
 * The collision map consists of entities of the type (appender name, FileNamePattern option)
 */
public static final String RFA_FILENAME_PATTERN_COLLISION_MAP = "RFA_FILENAME_PATTERN_COLLISION_MAP";

———————————————— initCollisionMaps end
——————————————— ContextBase end

日志创建缓存
this.loggerCache = new ConcurrentHashMap<String, Logger>();
创建日志上下文远程视图
this.loggerContextRemoteView = new LoggerContextVO(this);

——————————————— LoggerContextVO start

ch.qos.logback.classic.spi.LoggerContextVO

final String name;

final Map<String, String> propertyMap;

final long birthTime;

public LoggerContextVO(LoggerContext lc) {
	this.name = lc.getName();
	this.propertyMap = lc.getCopyOfPropertyMap();
	this.birthTime = lc.getBirthTime();
}

——————————————— LoggerContextVO end
旨在对外提供部分可视性

创建根日志
this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);
org.slf4j.Logger

final public String ROOT_LOGGER_NAME = "ROOT";

——————————————— Logger start

ch.qos.logback.classic.Logger

/**
 * The name of this logger
 */
private String name;

/**
 * The parent of this category. All categories have at least one ancestor
 * which is the root category.
 */
transient private Logger parent;

final transient LoggerContext loggerContext;

Logger(String name, Logger parent, LoggerContext loggerContext) {
	this.name = name;
	this.parent = parent;
	this.loggerContext = loggerContext;
}

transient关键字修饰的成员变量将不参与序列化
——————————————— Logger end
根日志命名为ROOT

设置根日志级别
this.root.setLevel(Level.DEBUG);
ch.qos.logback.classic.Level

public static final int DEBUG_INT = 10000;

/**
 * The <code>DEBUG</code> level designates informational events of lower
 * importance.
 */
public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG");

——————————————— Level start

ch.qos.logback.classic.Level

public final int levelInt;

public final String levelStr;

private Level(int levelInt, String levelStr) {
	this.levelInt = levelInt;
	this.levelStr = levelStr;
}

——————————————— Level end
——————————————— setLevel start

ch.qos.logback.classic.Logger

public synchronized void setLevel(Level newLevel) {
	if (level == newLevel) {
		// nothing to do;
		return;
	}
	if (newLevel == null && isRootLogger()) {
		throw new IllegalArgumentException("The level of the root logger cannot be set to null");
	}

	level = newLevel;
	if (newLevel == null) {
		effectiveLevelInt = parent.effectiveLevelInt;
		newLevel = parent.getEffectiveLevel();
	} else {
		effectiveLevelInt = newLevel.levelInt;
	}

	if (childrenList != null) {
		int len = childrenList.size();
		for (int i = 0; i < len; i++) {
			Logger child = (Logger) childrenList.get(i);
			// tell child to handle parent levelInt change
			child.handleParentLevelChange(effectiveLevelInt);
		}
	}
	// inform listeners
	loggerContext.fireOnLevelChange(this, newLevel);
}
对比新旧等级
if (level == newLevel) {
	// nothing to do;
	return;
}
判断新等级是否符合
if (newLevel == null && isRootLogger()) {
	throw new IllegalArgumentException("The level of the root logger cannot be set to null");
}

———————————————— isRootLogger start

ch.qos.logback.classic.Logger

private boolean isRootLogger() {
	// only the root logger has a null parent
	return parent == null;
}

仅根日志父日志为null
———————————————— isRootLogger end
即根日志等级不可为空

获取有效的等级数值
level = newLevel;
if (newLevel == null) {
	effectiveLevelInt = parent.effectiveLevelInt;
	newLevel = parent.getEffectiveLevel();
} else {
	effectiveLevelInt = newLevel.levelInt;
}

未指定等级时,使用父日志的等级数值

遍历子日志集合,使其处理等级变化
ch.qos.logback.classic.Logger

if (childrenList != null) {
	int len = childrenList.size();
	for (int i = 0; i < len; i++) {
		Logger child = (Logger) childrenList.get(i);
		// tell child to handle parent levelInt change
		child.handleParentLevelChange(effectiveLevelInt);
	}
}

———————————————— handleParentLevelChange start

ch.qos.logback.classic.Logger

private synchronized void handleParentLevelChange(int newParentLevelInt) {
	// changes in the parent levelInt affect children only if their levelInt is
	// null
	if (level == null) {
		effectiveLevelInt = newParentLevelInt;

		// propagate the parent levelInt change to this logger's children
		if (childrenList != null) {
			int len = childrenList.size();
			for (int i = 0; i < len; i++) {
				Logger child = (Logger) childrenList.get(i);
				child.handleParentLevelChange(newParentLevelInt);
			}
		}
	}
}

递归调用子日志处理等级变化
———————————————— handleParentLevelChange end

通知等级变化
loggerContext.fireOnLevelChange(this, newLevel);

———————————————— fireOnLevelChange start

ch.qos.logback.classic.LoggerContext

final private List<LoggerContextListener> loggerContextListenerList = new ArrayList<LoggerContextListener>();

void fireOnLevelChange(Logger logger, Level level) {
	for (LoggerContextListener listener : loggerContextListenerList) {
		listener.onLevelChange(logger, level);
	}
}

当前为设置过日志上下文监听器,loggerContextListenerList为空
———————————————— fireOnLevelChange end
——————————————— setLevel end
将根日志设置为DEBUG级别

添加根日志缓存
loggerCache.put(Logger.ROOT_LOGGER_NAME, root);
初始化评估集合
initEvaluatorMap();

——————————————— initEvaluatorMap start

ch.qos.logback.classic.LoggerContext

void initEvaluatorMap() {
	putObject(EVALUATOR_MAP, new HashMap<String, EventEvaluator<?>>());
}
ch.qos.logback.core.CoreConstants

/**
 * The key used in locating the evaluator map in context's object map.
 */
public static final String EVALUATOR_MAP = "EVALUATOR_MAP";

——————————————— initEvaluatorMap end

设置大小
size = 1;
创建框架包集合
this.frameworkPackages = new ArrayList<String>();

—————————————— LoggerContext end

设置默认日志上下文名称
ch.qos.logback.core.CoreConstants

public static final String DEFAULT_CONTEXT_NAME = "default";

—————————————— setName start

ch.qos.logback.classic.LoggerContext

@Override
public void setName(String name) {
	super.setName(name);
	updateLoggerContextVO();
}
使用父级方法设置名称
super.setName(name);

——————————————— setName start

ch.qos.logback.core.ContextBase

public void setName(String name) throws IllegalStateException {
	if (name != null && name.equals(this.name)) {
		return; // idempotent naming
	}
	if (this.name == null || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
		this.name = name;
	} else {
		throw new IllegalStateException("Context has been already given a name");
	}
}

仅名称不存在或为默认名称default时可设置
——————————————— setName end

更新日志上下文视图
updateLoggerContextVO();

——————————————— updateLoggerContextVO start

ch.qos.logback.classic.LoggerContext

private void updateLoggerContextVO() {
	loggerContextRemoteView = new LoggerContextVO(this);
}

——————————————— updateLoggerContextVO end
—————————————— setName end
————————————— StaticLoggerBinder end

初始化

————————————— init start

org.slf4j.impl.StaticLoggerBinder

void init() {
	try {
		try {
			new ContextInitializer(defaultLoggerContext).autoConfig();
		} catch (JoranException je) {
			Util.report("Failed to auto configure default logger context", je);
		}
		// logback-292
		if (!StatusUtil.contextHasStatusListener(defaultLoggerContext)) {
			StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
		}
		contextSelectorBinder.init(defaultLoggerContext, KEY);
		initialized = true;
	} catch (Exception t) { // see LOGBACK-1159
		Util.report("Failed to instantiate [" + LoggerContext.class.getName() + "]", t);
	}
}
创建上下文初始化器并自动配置
new ContextInitializer(defaultLoggerContext).autoConfig();
查看构造方法

—————————————— ContextInitializer start

ch.qos.logback.classic.util.ContextInitializer

final LoggerContext loggerContext;

public ContextInitializer(LoggerContext loggerContext) {
	this.loggerContext = loggerContext;
}

—————————————— ContextInitializer end

自动配置

—————————————— autoConfig start

ch.qos.logback.classic.util.ContextInitializer

public void autoConfig() throws JoranException {
	StatusListenerConfigHelper.installIfAsked(loggerContext);
	URL url = findURLOfDefaultConfigurationFile(true);
	if (url != null) {
		configureByResource(url);
	} else {
		Configurator c = EnvUtil.loadFromServiceLoader(Configurator.class);
		if (c != null) {
			try {
				c.setContext(loggerContext);
				c.configure(loggerContext);
			} catch (Exception e) {
				throw new LogbackException(String.format("Failed to initialize Configurator: %s using ServiceLoader", c != null ? c.getClass()
								.getCanonicalName() : "null"), e);
			}
		} else {
			BasicConfigurator basicConfigurator = new BasicConfigurator();
			basicConfigurator.setContext(loggerContext);
			basicConfigurator.configure(loggerContext);
		}
	}
}
设置状态监听器
StatusListenerConfigHelper.installIfAsked(loggerContext);

——————————————— installIfAsked start

ch.qos.logback.core.util.StatusListenerConfigHelper

public static void installIfAsked(Context context) {
	String slClass = OptionHelper.getSystemProperty(CoreConstants.STATUS_LISTENER_CLASS_KEY);
	if (!OptionHelper.isEmpty(slClass)) {
		addStatusListener(context, slClass);
	}
}
从系统属性获取状态监听器名称
String slClass = OptionHelper.getSystemProperty(CoreConstants.STATUS_LISTENER_CLASS_KEY);
ch.qos.logback.core.CoreConstants

final public static String STATUS_LISTENER_CLASS_KEY = "logback.statusListenerClass";

———————————————— getSystemProperty start

ch.qos.logback.core.util.OptionHelper

public static String getSystemProperty(String key) {
	try {
		return System.getProperty(key);
	} catch (SecurityException e) {
		return null;
	}
}

———————————————— getSystemProperty end
默认无监听器配置,即logback.statusListenerClass配置为null
——————————————— installIfAsked end

查找默认配置文件路径
URL url = findURLOfDefaultConfigurationFile(true);

——————————————— findURLOfDefaultConfigurationFile start

ch.qos.logback.classic.util.ContextInitializer

public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
	ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
	URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
	if (url != null) {
		return url;
	}

	url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
	if (url != null) {
		return url;
	}
    
	return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
}
获取当前实例的类加载器
ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);

———————————————— getClassLoaderOfObject start

ch.qos.logback.core.util.Loader

public static ClassLoader getClassLoaderOfObject(Object o) {
	if (o == null) {
		throw new NullPointerException("Argument cannot be null");
	}
	return getClassLoaderOfClass(o.getClass());
}

————————————————— getClassLoaderOfClass start

ch.qos.logback.core.util.Loader

public static ClassLoader getClassLoaderOfClass(final Class<?> clazz) {
	ClassLoader cl = clazz.getClassLoader();
	if (cl == null) {
		return ClassLoader.getSystemClassLoader();
	} else {
		return cl;
	}
}

————————————————— getClassLoaderOfClass end
———————————————— getClassLoaderOfObject end

从系统属性查找配置文件地址
URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);

———————————————— findConfigFileURLFromSystemProperties start

ch.qos.logback.classic.util.ContextInitializer

private URL findConfigFileURLFromSystemProperties(ClassLoader classLoader, boolean updateStatus) {
	String logbackConfigFile = OptionHelper.getSystemProperty(CONFIG_FILE_PROPERTY);
	if (logbackConfigFile != null) {
		URL result = null;
		try {
			result = new URL(logbackConfigFile);
			return result;
		} catch (MalformedURLException e) {
			// so, resource is not a URL:
			// attempt to get the resource from the class path
			result = Loader.getResource(logbackConfigFile, classLoader);
			if (result != null) {
				return result;
			}
			File f = new File(logbackConfigFile);
			if (f.exists() && f.isFile()) {
				try {
					result = f.toURI().toURL();
					return result;
				} catch (MalformedURLException e1) {
				}
			}
		} finally {
			if (updateStatus) {
				statusOnResourceSearch(logbackConfigFile, classLoader, result);
			}
		}
	}
	return null;
}
从系统属性获取配置文件值
String logbackConfigFile = OptionHelper.getSystemProperty(CONFIG_FILE_PROPERTY);
ch.qos.logback.classic.util.ContextInitializer

final public static String CONFIG_FILE_PROPERTY = "logback.configurationFile";

默认logback.configurationFile未配置,返回null

若值不为null,则将值按如下顺序逐一尝试
  1. 完整的资源地址
result = new URL(logbackConfigFile);
return result;
  1. 类路径相对资源地址
result = Loader.getResource(logbackConfigFile, classLoader);
if (result != null) {
	return result;
}

————————————————— getResource start

ch.qos.logback.core.util.Loader

public static URL getResource(String resource, ClassLoader classLoader) {
	try {
		return classLoader.getResource(resource);
	} catch (Throwable t) {
		return null;
	}
}

————————————————— getResource end
3. 文件路径

File f = new File(logbackConfigFile);
if (f.exists() && f.isFile()) {
	try {
		result = f.toURI().toURL();
		return result;
	} catch (MalformedURLException e1) {
	}
}
记录资源搜索状态
if (updateStatus) {
	statusOnResourceSearch(logbackConfigFile, classLoader, result);
}

————————————————— statusOnResourceSearch start

ch.qos.logback.classic.util.ContextInitializer

private void statusOnResourceSearch(String resourceName, ClassLoader classLoader, URL url) {
	StatusManager sm = loggerContext.getStatusManager();
	if (url == null) {
		sm.add(new InfoStatus("Could NOT find resource [" + resourceName + "]", loggerContext));
	} else {
		sm.add(new InfoStatus("Found resource [" + resourceName + "] at [" + url.toString() + "]", loggerContext));
		multiplicityWarning(resourceName, classLoader);
	}
}
获取状态管理器
StatusManager sm = loggerContext.getStatusManager();

—————————————————— getStatusManager start

ch.qos.logback.core.ContextBase

private StatusManager sm = new BasicStatusManager();

public StatusManager getStatusManager() {
	return sm;
}

—————————————————— getStatusManager end

创建状态实例并添加
sm.add(new InfoStatus("Found resource [" + resourceName + "] at [" + url.toString() + "]", loggerContext));
查看状态构造方法

—————————————————— InfoStatus start

ch.qos.logback.core.status.InfoStatus

public InfoStatus(String msg, Object origin) {
	super(Status.INFO, msg, origin);
}
ch.qos.logback.core.status.Status

int INFO = 0;
查看父类构造方法
ch.qos.logback.core.status.StatusBase

int level;

final String message;

final Object origin;

Throwable throwable;

long date;

StatusBase(int level, String msg, Object origin) {
	this(level, msg, origin, null);
}

StatusBase(int level, String msg, Object origin, Throwable t) {
	this.level = level;
	this.message = msg;
	this.origin = origin;
	this.throwable = t;
	this.date = System.currentTimeMillis();
}

—————————————————— InfoStatus end

添加至状态管理器

—————————————————— add start

ch.qos.logback.core.BasicStatusManager

public static final int MAX_HEADER_COUNT = 150;

public static final int TAIL_SIZE = 150;

int count = 0;

final protected List<Status> statusList = new ArrayList<Status>();

final protected CyclicBuffer<Status> tailBuffer = new CyclicBuffer<Status>(TAIL_SIZE);

final protected LogbackLock statusListLock = new LogbackLock();

int level = Status.INFO;

public void add(Status newStatus) {
	// LBCORE-72: fire event before the count check
	fireStatusAddEvent(newStatus);

	count++;
	if (newStatus.getLevel() > level) {
		level = newStatus.getLevel();
	}

	synchronized (statusListLock) {
		if (statusList.size() < MAX_HEADER_COUNT) {
			statusList.add(newStatus);
		} else {
			tailBuffer.add(newStatus);
		}
	}

}
触发状态添加事件
fireStatusAddEvent(newStatus);

——————————————————— fireStatusAddEvent start

ch.qos.logback.core.BasicStatusManager

final protected List<StatusListener> statusListenerList = new ArrayList<StatusListener>();

final protected LogbackLock statusListenerListLock = new LogbackLock();

private void fireStatusAddEvent(Status status) {
	synchronized (statusListenerListLock) {
		for (StatusListener sl : statusListenerList) {
			sl.addStatusEvent(status);
		}
	}
}

遍历状态监听器集合并添加状态事件
——————————————————— fireStatusAddEvent end
当前监听器集合为空

计数增加
count++;
更新最大状态等级
if (newStatus.getLevel() > level) {
	level = newStatus.getLevel();
}
添加状态实例
if (statusList.size() < MAX_HEADER_COUNT) {
	statusList.add(newStatus);
} else {
	tailBuffer.add(newStatus);
}

若状态集合长度小于最大头部计数,将状态实例添加至集合
否则将状态实例添加至尾部缓冲区
—————————————————— add end

多重警告
multiplicityWarning(resourceName, classLoader);

—————————————————— multiplicityWarning start

ch.qos.logback.classic.util.ContextInitializer

private void multiplicityWarning(String resourceName, ClassLoader classLoader) {
	Set<URL> urlSet = null;
	StatusManager sm = loggerContext.getStatusManager();
        try {
		urlSet = Loader.getResources(resourceName, classLoader);
	} catch (IOException e) {
		sm.add(new ErrorStatus("Failed to get url list for resource [" + resourceName + "]", loggerContext, e));
	}
	if (urlSet != null && urlSet.size() > 1) {
		sm.add(new WarnStatus("Resource [" + resourceName + "] occurs multiple times on the classpath.", loggerContext));
		for (URL url : urlSet) {
			sm.add(new WarnStatus("Resource [" + resourceName + "] occurs at [" + url.toString() + "]", loggerContext));
		}
	}
}

若指定资源存在多个,则添加告警状态
—————————————————— multiplicityWarning end
————————————————— statusOnResourceSearch end
———————————————— findConfigFileURLFromSystemProperties end
若未发现配置,则继续

从类加载路径查找配置文件
url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
ch.qos.logback.classic.util.ContextInitializer

final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";

查找logback-test.xml文件
———————————————— getResource start

ch.qos.logback.classic.util.ContextInitializer

private URL getResource(String filename, ClassLoader myClassLoader, boolean updateStatus) {
	URL url = Loader.getResource(filename, myClassLoader);
	if (updateStatus) {
		statusOnResourceSearch(filename, myClassLoader, url);
	}
	return url;
}

———————————————— getResource end
若未发现配置,则继续

从类加载路径查找配置文件java
return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
ch.qos.logback.classic.util.ContextInitializer

final public static String AUTOCONFIG_FILE = "logback.xml";

查找logback.xml文件
——————————————— findURLOfDefaultConfigurationFile end

若存在配置
configureByResource(url);

——————————————— configureByResource start

ch.qos.logback.classic.util.ContextInitializer

public void configureByResource(URL url) throws JoranException {
	if (url == null) {
		throw new IllegalArgumentException("URL argument cannot be null");
	}
	final String urlString = url.toString();
	if (urlString.endsWith("xml")) {
		JoranConfigurator configurator = new JoranConfigurator();
		configurator.setContext(loggerContext);
		configurator.doConfigure(url);
	} else {
		throw new LogbackException("Unexpected filename extension of file [" + url.toString() + "]. Should be .xml");
	}
}

创建ch.qos.logback.classic.joran.JoranConfigurator实例并进行配置
——————————————— configureByResource end

若无配置文件,读取或创建配置器并配置
先尝试读取配置器
Configurator c = EnvUtil.loadFromServiceLoader(Configurator.class);

——————————————— loadFromServiceLoader start

ch.qos.logback.classic.util.EnvUtil

public static <T> T loadFromServiceLoader(Class<T> c) {
	ServiceLoader<T> loader = ServiceLoader.load(c, getServiceLoaderClassLoader());
	Iterator<T> it = loader.iterator();
	if (it.hasNext())
		return it.next();
	return null;
}

即通过SPI机制获取第一个实现类
——————————————— loadFromServiceLoader end
默认无配置

未找到实现类,则创建配置器
BasicConfigurator basicConfigurator = new BasicConfigurator();
设置上下文
basicConfigurator.setContext(loggerContext);

——————————————— setContext start

ch.qos.logback.core.spi.ContextAwareBase

protected Context context;

public void setContext(Context context) {
	if (this.context == null) {
		this.context = context;
	} else if (this.context != context) {
		throw new IllegalStateException("Context has been already set");
	}
}

仅可设置一次
——————————————— setContext end

进行配置
basicConfigurator.configure(loggerContext);

——————————————— configure start

ch.qos.logback.classic.BasicConfigurator

public void configure(LoggerContext lc) {
	addInfo("Setting up default configuration.");
        
	ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
	ca.setContext(lc);
	ca.setName("console");
	LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<ILoggingEvent>();
	encoder.setContext(lc);
        
 
	// same as 
	// PatternLayout layout = new PatternLayout();
	// layout.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
	TTLLLayout layout = new TTLLLayout();
 
	layout.setContext(lc);
	layout.start();
	encoder.setLayout(layout);
        
	ca.setEncoder(encoder);
	ca.start();
        
	Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
	rootLogger.addAppender(ca);
}
添加信息状态
addInfo("Setting up default configuration.");

———————————————— addInfo start

ch.qos.logback.core.spi.ContextAwareBase

public void addInfo(String msg) {
	addStatus(new InfoStatus(msg, getDeclaredOrigin()));
}

getDeclaredOrigin()方法获取原始上下文实例
————————————————— getDeclaredOrigin start

ch.qos.logback.core.spi.ContextAwareBase

final Object declaredOrigin;

protected Object getDeclaredOrigin() {
	return declaredOrigin;
}
查看无参构造方法

—————————————————— ContextAwareBase start

ch.qos.logback.core.spi.ContextAwareBase

final Object declaredOrigin;

public ContextAwareBase() {
	declaredOrigin = this;
}

默认为自身
—————————————————— ContextAwareBase end
————————————————— getDeclaredOrigin end
可知此处获取的实例即为前面创建的ch.qos.logback.classic.BasicConfigurator

添加状态

————————————————— addStatus start

ch.qos.logback.core.spi.ContextAwareBase

public void addStatus(Status status) {
	if (context == null) {
		if (noContextWarning++ == 0) {
			System.out.println("LOGBACK: No context given for " + this);
		}
		return;
	}
	StatusManager sm = context.getStatusManager();
	if (sm != null) {
		sm.add(status);
	}
}

————————————————— addStatus end
———————————————— addInfo end

创建控制台附加器
ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
ca.setContext(lc);
ca.setName("console");
创建布局编码器及布局实例并设置
LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<ILoggingEvent>();
encoder.setContext(lc);
        
 
// same as 
// PatternLayout layout = new PatternLayout();
// layout.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
TTLLLayout layout = new TTLLLayout();
 
layout.setContext(lc);
layout.start();
encoder.setLayout(layout);
为控制台附加器设置编码器并启动
ca.setEncoder(encoder);
ca.start();
将控制台附加器添加至根日志实例
Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.addAppender(ca);

——————————————— configure end
—————————————— autoConfig end

判断日志上下文是否有状态监听器
StatusUtil.contextHasStatusListener(defaultLoggerContext)

—————————————— contextHasStatusListener start

ch.qos.logback.core.status.StatusUtil

static public boolean contextHasStatusListener(Context context) {
	StatusManager sm = context.getStatusManager();
	if (sm == null)
		return false;
	List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
	if (listeners == null || listeners.size() == 0)
		return false;
	else
		return true;
}

—————————————— contextHasStatusListener end
前面已知状态监听器集合为空

打印错误或警告信息
StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);

—————————————— printInCaseOfErrorsOrWarnings start

ch.qos.logback.core.util.StatusPrinter

public static void printInCaseOfErrorsOrWarnings(Context context) {
	printInCaseOfErrorsOrWarnings(context, 0);
}

public static void printInCaseOfErrorsOrWarnings(Context context, long threshold) {
	if (context == null) {
		throw new IllegalArgumentException("Context argument cannot be null");
	}

	StatusManager sm = context.getStatusManager();
	if (sm == null) {
		ps.println("WARN: Context named \"" + context.getName() + "\" has no status manager");
	} else {
		StatusUtil statusUtil = new StatusUtil(context);
		if (statusUtil.getHighestLevel(threshold) >= ErrorStatus.WARN) {
			print(sm, threshold);
		}
	}
}
创建状态工具
StatusUtil statusUtil = new StatusUtil(context);

——————————————— StatusUtil start

ch.qos.logback.core.status.StatusUtil

StatusManager sm;

public StatusUtil(Context context) {
	this.sm = context.getStatusManager();
}

——————————————— StatusUtil end

获取最高级别
statusUtil.getHighestLevel(threshold)

——————————————— getHighestLevel start

ch.qos.logback.core.status.StatusUtil

public int getHighestLevel(long threshold) {
	List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
	int maxLevel = Status.INFO;
	for (Status s : filteredList) {
		if (s.getLevel() > maxLevel)
			maxLevel = s.getLevel();
	}
	return maxLevel;
}
根据时间阈值过滤状态集合
List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);

———————————————— filterStatusListByTimeThreshold start

ch.qos.logback.core.status.StatusUtil

static public List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
	List<Status> filteredList = new ArrayList<Status>();
	for (Status s : rawList) {
		if (s.getDate() >= threshold)
			filteredList.add(s);
		}
	return filteredList;
}

可知threshold为状态时间戳阈值,0即全部状态
———————————————— filterStatusListByTimeThreshold end
——————————————— getHighestLevel end
最终返回高于INFO的最高级别

当最高级别大于或等于WARN时,打印状态
print(sm, threshold);

——————————————— print start

ch.qos.logback.core.util.StatusPrinter

public static void print(StatusManager sm, long threshold) {
	StringBuilder sb = new StringBuilder();
	List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
	buildStrFromStatusList(sb, filteredList);
	ps.println(sb.toString());
}
构建状态集合字符串
buildStrFromStatusList(sb, filteredList);
打印
ps.println(sb.toString());
ch.qos.logback.core.util.StatusPrinter

private static PrintStream ps = System.out;

即控制台输出
——————————————— print end
—————————————— printInCaseOfErrorsOrWarnings end

初始化上下文选择器装订器
contextSelectorBinder.init(defaultLoggerContext, KEY);
先看defaultLoggerContext
org.slf4j.impl.StaticLoggerBinder

private final ContextSelectorStaticBinder contextSelectorBinder = ContextSelectorStaticBinder.getSingleton();

—————————————— ContextSelectorStaticBinder start

ch.qos.logback.classic.util.ContextSelectorStaticBinder

static ContextSelectorStaticBinder singleton = new ContextSelectorStaticBinder();

public static ContextSelectorStaticBinder getSingleton() {
	return singleton;
}

—————————————— ContextSelectorStaticBinder end

接着看KEY
org.slf4j.impl.StaticLoggerBinder

private static Object KEY = new Object();
初始化

—————————————— init start

ch.qos.logback.classic.util.ContextSelectorStaticBinder

public void init(LoggerContext defaultLoggerContext, Object key) throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
				IllegalAccessException, InvocationTargetException {
	if (this.key == null) {
		this.key = key;
	} else if (this.key != key) {
		throw new IllegalAccessException("Only certain classes can access this method.");
	}

	String contextSelectorStr = OptionHelper.getSystemProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR);
	if (contextSelectorStr == null) {
		contextSelector = new DefaultContextSelector(defaultLoggerContext);
	} else if (contextSelectorStr.equals("JNDI")) {
		// if jndi is specified, let's use the appropriate class
		contextSelector = new ContextJNDISelector(defaultLoggerContext);
	} else {
		contextSelector = dynamicalContextSelector(defaultLoggerContext, contextSelectorStr);
	}
}
从系统属性中获取配置的值
String contextSelectorStr = OptionHelper.getSystemProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR);
ch.qos.logback.classic.ClassicConstants

public static final String LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
根据获取的值创建上下文选择器
  • 值为nullch.qos.logback.classic.selector.DefaultContextSelector,默认上下文选择器
  • 值为JNDIch.qos.logback.classic.selector.ContextJNDISelector
  • 值可能为类名,动态创建实例

——————————————— dynamicalContextSelector start

ch.qos.logback.classic.util.ContextSelectorStaticBinder

static ContextSelector dynamicalContextSelector(LoggerContext defaultLoggerContext, String contextSelectorStr) throws ClassNotFoundException,
					SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException,
					InvocationTargetException {
	Class<?> contextSelectorClass = Loader.loadClass(contextSelectorStr);
	Constructor cons = contextSelectorClass.getConstructor(new Class[] { LoggerContext.class });
	return (ContextSelector) cons.newInstance(defaultLoggerContext);
}

——————————————— dynamicalContextSelector end
—————————————— init end

初始化完成
initialized = true;

————————————— init end
———————————— getSingleton end

接着获取其日志工厂实例

———————————— getLoggerFactory start

org.slf4j.impl.StaticLoggerBinder

public ILoggerFactory getLoggerFactory() {
	if (!initialized) {
		return defaultLoggerContext;
	}

	if (contextSelectorBinder.getContextSelector() == null) {
		throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL);
	}
	return contextSelectorBinder.getContextSelector().getLoggerContext();
}

此时已完成初始化

返回日志上下文
return contextSelectorBinder.getContextSelector().getLoggerContext();

获取上下文选择器
————————————— getContextSelector start

ch.qos.logback.classic.util.ContextSelectorStaticBinder

public ContextSelector getContextSelector() {
	return contextSelector;
}

————————————— getContextSelector end
通过选择器获取上下文
————————————— getLoggerContext start

ch.qos.logback.classic.selector.DefaultContextSelector

public LoggerContext getLoggerContext() {
	return getDefaultLoggerContext();
}

—————————————— getDefaultLoggerContext start

ch.qos.logback.classic.selector.DefaultContextSelector

public LoggerContext getDefaultLoggerContext() {
	return defaultLoggerContext;
}

—————————————— getDefaultLoggerContext end
获取到前面名为default的默认日志上下文
————————————— getLoggerContext end
———————————— getLoggerFactory end

判断实例是否属于ch.qos.logback.classic.LoggerContext
Assert.isInstanceOf(LoggerContext.class, factory,
		() -> String.format(
					"LoggerFactory is not a Logback LoggerContext but Logback is on "
						+ "the classpath. Either remove Logback or the competing "
						+ "implementation (%s loaded from %s). If you are using "
						+ "WebLogic you will need to add 'org.slf4j' to "
						+ "prefer-application-packages in WEB-INF/weblogic.xml",
				factory.getClass(), getLocation(factory)));
转换实例类型并返回
return (LoggerContext) factory;

——————————— getLoggerContext end

判断日志上下文实例是否初始化完成
if (isAlreadyInitialized(loggerContext)) {
	return;
}

——————————— isAlreadyInitialized start

org.springframework.boot.logging.logback.LogbackLoggingSystem

private boolean isAlreadyInitialized(LoggerContext loggerContext) {
	return loggerContext.getObject(LoggingSystem.class.getName()) != null;
}

———————————— getObject start

ch.qos.logback.core.ContextBase

Map<String, Object> objectMap = new HashMap<String, Object>();

public Object getObject(String key) {
	return objectMap.get(key);
}

———————————— getObject end
此时尚未初始化,objectMap中无键org.springframework.boot.logging.LoggingSystem
——————————— isAlreadyInitialized end

父类预初始化
super.beforeInitialize();

——————————— beforeInitialize end

org.springframework.boot.logging.Slf4JLoggingSystem

@Override
public void beforeInitialize() {
	super.beforeInitialize();
	configureJdkLoggingBridgeHandler();
}
父类预初始化
super.beforeInitialize();

———————————— beforeInitialize start

org.springframework.boot.logging.AbstractLoggingSystem

@Override
public void beforeInitialize() {
}

———————————— beforeInitialize end
父类方法为空

配置jdk日志桥接处理器
configureJdkLoggingBridgeHandler();

———————————— configureJdkLoggingBridgeHandler start

org.springframework.boot.logging.Slf4JLoggingSystem

private void configureJdkLoggingBridgeHandler() {
	try {
		if (isBridgeJulIntoSlf4j()) {
			removeJdkLoggingBridgeHandler();
			SLF4JBridgeHandler.install();
		}
	}
	catch (Throwable ex) {
		// Ignore. No java.util.logging bridge is installed.
	}
}
判断是否将JUL桥接至SLF4J
if (isBridgeJulIntoSlf4j())

————————————— isBridgeJulIntoSlf4j start

org.springframework.boot.logging.Slf4JLoggingSystem

protected final boolean isBridgeJulIntoSlf4j() {
	return isBridgeHandlerAvailable() && isJulUsingASingleConsoleHandlerAtMost();
}
判断桥接处理器是否可用
isBridgeHandlerAvailable()

—————————————— isBridgeHandlerAvailable start

org.springframework.boot.logging.Slf4JLoggingSystem

private static final String BRIDGE_HANDLER = "org.slf4j.bridge.SLF4JBridgeHandler";

protected final boolean isBridgeHandlerAvailable() {
	return ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader());
}

—————————————— isBridgeHandlerAvailable end
即是否存在org.slf4j.bridge.SLF4JBridgeHandler

判断JUL是否至多使用一个控制台处理器
isJulUsingASingleConsoleHandlerAtMost()

—————————————— isJulUsingASingleConsoleHandlerAtMost start

org.springframework.boot.logging.Slf4JLoggingSystem

private boolean isJulUsingASingleConsoleHandlerAtMost() {
	Logger rootLogger = LogManager.getLogManager().getLogger("");
	Handler[] handlers = rootLogger.getHandlers();
	return handlers.length == 0 || (handlers.length == 1 && handlers[0] instanceof ConsoleHandler);
}
获取根日志实例
Logger rootLogger = LogManager.getLogManager().getLogger("");
获取处理器
Handler[] handlers = rootLogger.getHandlers();
判断处理器是否仅为一个且为java.util.logging.ConsoleHandler或其子实例
return handlers.length == 0 || (handlers.length == 1 && handlers[0] instanceof ConsoleHandler);

—————————————— isJulUsingASingleConsoleHandlerAtMost end
————————————— isBridgeJulIntoSlf4j end
以上条件均满足,继续

移除jdk日志桥接处理器
removeJdkLoggingBridgeHandler();

————————————— removeJdkLoggingBridgeHandler start

org.springframework.boot.logging.Slf4JLoggingSystem

private void removeJdkLoggingBridgeHandler() {
	try {
		removeDefaultRootHandler();
		SLF4JBridgeHandler.uninstall();
	}
	catch (Throwable ex) {
		// Ignore and continue
	}
}
移除默认的根处理器
removeDefaultRootHandler();

—————————————— removeDefaultRootHandler start

org.springframework.boot.logging.Slf4JLoggingSystem

private void removeDefaultRootHandler() {
	try {
		Logger rootLogger = LogManager.getLogManager().getLogger("");
		Handler[] handlers = rootLogger.getHandlers();
		if (handlers.length == 1 && handlers[0] instanceof ConsoleHandler) {
			rootLogger.removeHandler(handlers[0]);
		}
	}
	catch (Throwable ex) {
		// Ignore and continue
	}
}

—————————————— removeDefaultRootHandler end

卸载SLF4J桥接处理器
SLF4JBridgeHandler.uninstall();

—————————————— uninstall start

org.slf4j.bridge.SLF4JBridgeHandler

public static void uninstall() throws SecurityException {
	java.util.logging.Logger rootLogger = getRootLogger();
	Handler[] handlers = rootLogger.getHandlers();
	for (int i = 0; i < handlers.length; i++) {
		if (handlers[i] instanceof SLF4JBridgeHandler) {
			rootLogger.removeHandler(handlers[i]);
		}
	}
}

—————————————— uninstall end
————————————— removeJdkLoggingBridgeHandler end

安装SLF4J桥接处理器
SLF4JBridgeHandler.install();
org.slf4j.bridge.SLF4JBridgeHandler

public static void install() {
	LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
}

———————————— configureJdkLoggingBridgeHandler end
——————————— beforeInitialize end
至此,org.springframework.boot.logging.Slf4JLoggingSystem预初始化完成

在日志上下文实例中加入过滤器
loggerContext.getTurboFilterList().add(FILTER);
org.springframework.boot.logging.Slf4JLoggingSystem

private static final TurboFilter FILTER = new TurboFilter() {

	@Override
	public FilterReply decide(Marker marker, ch.qos.logback.classic.Logger logger, Level level, String format,
			Object[] params, Throwable t) {
		return FilterReply.DENY;
	}

};

ch.qos.logback.classic.turbo.TurboFilter定义了public abstract FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t);抽象方法,通过返回值决定是否对日志过滤
FILTERdecide方法始终返回ch.qos.logback.core.spi.FilterReply.DENY这将过滤掉所有的日志输出
——————————— getTurboFilterList start

ch.qos.logback.classic.LoggerContext

private final TurboFilterList turboFilterList = new TurboFilterList();

public TurboFilterList getTurboFilterList() {
	return turboFilterList;
}

——————————— getTurboFilterList end
ch.qos.logback.classic.spi.TurboFilterList继承自java.util.concurrent.CopyOnWriteArrayList
—————————— beforeInitialize end
————————— onApplicationStartingEvent end
———————— onApplicationEvent end
至此org.springframework.boot.context.logging.LoggingApplicationListener监听器完成了对org.springframework.boot.context.event.ApplicationStartingEvent事件的处理

接着是org.springframework.boot.autoconfigure.BackgroundPreinitializer

———————— onApplicationEvent start

org.springframework.boot.autoconfigure.BackgroundPreinitializer

@Override
public void onApplicationEvent(SpringApplicationEvent event) {
	if (!ENABLED) {
		return;
	}
	if (event instanceof ApplicationEnvironmentPreparedEvent
			&& preinitializationStarted.compareAndSet(false, true)) {
		performPreinitialization();
	}
	if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent)
			&& preinitializationStarted.get()) {
		try {
			preinitializationComplete.await();
		}
		catch (InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
	}
}

———————— onApplicationEvent end
未匹配当前事件类型ApplicationStartingEvent,跳过

最后是org.springframework.boot.context.config.DelegatingApplicationListener

———————— onApplicationEvent start

org.springframework.boot.context.config.DelegatingApplicationListener

@Override
public void onApplicationEvent(ApplicationEvent event) {
	if (event instanceof ApplicationEnvironmentPreparedEvent) {
		List<ApplicationListener<ApplicationEvent>> delegates = getListeners(
				((ApplicationEnvironmentPreparedEvent) event).getEnvironment());
		if (delegates.isEmpty()) {
			return;
		}
		this.multicaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<ApplicationEvent> listener : delegates) {
			this.multicaster.addApplicationListener(listener);
		}
	}
	if (this.multicaster != null) {
		this.multicaster.multicastEvent(event);
	}
}

———————— onApplicationEvent end
同样未匹配当前事件类型ApplicationStartingEvent,跳过
——————— doInvokeListener end
—————— invokeListener end
————— for end
———— multicastEvent end
——— starting end

步骤处理

if (stepAction != null) {
	stepAction.accept(step);
}

步骤结束

step.end();

—— doWithListeners end
— starting end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值