概述
SpringApplication#run方法
- 第一步:StopWatch
- 第二步:configureHeadlessProperty
- 第三步:SpringApplicationRunListeners
- getRunListeners(args)方法:
- listeners.starting()方法:
初始化SpringApplication之后,执行run方法,来创建和刷新一个ApplicationContext:
public ConfigurableApplicationContext run(String... args) {
//1、任务计时器,调用start开始计时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 2、设置系统属性java.awt.headless,这里设置为true(Headless模式是在缺少显示屏、键盘或者鼠标时的系统配置)
configureHeadlessProperty();
// 3、使用SpringFactoriesLoader,获取资源文件中的SpringApplicationRunListener,此处是EventPublishingRunListener,并starting
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
//4、创建一个DefaultApplicationArguments对象持有的是传进来的参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
// 5、打印banner
Banner printedBanner = printBanner(environment);
// 6、创建context
context = createApplicationContext();
// 7、初始化FailureAnalyzers,借助SpringFactoriesLoader,创建Error Reporters
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 8、调用prepareContext,context相关的重要处理
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 9、用AbstractApplicationContext#refresh方法,并注册钩子
refreshContext(context);
// 10、刷新的后置处理,未做操作
afterRefresh(context, applicationArguments);
// 11、停止计时
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
// 12、在容器完成刷新后,依次调用注册的Runners
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
主要的步骤标注在了代码里,以下做个简要的分析
第一步:StopWatch
StopWatch stopWatch = new StopWatch();
stopWatch.start();
start方法:
public void start() throws IllegalStateException {
// 启动一个未命名的task
start("");
}
// start
public void start(String taskName) throws IllegalStateException {
// 当前taskName不为null时,抛出异常
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");
}
this.currentTaskName = taskName;
this.startTimeNanos = System.nanoTime();
}
在run方法11步中,结束计时。此方法比较简单。
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
}
long lastTime = System.nanoTime() - this.startTimeNanos;
// task耗时
this.totalTimeNanos += lastTime;
// task基本信息(名称和结束时间)
this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
if (this.keepTaskList) {
this.taskList.add(this.lastTaskInfo);
}
// task数量
++this.taskCount;
this.currentTaskName = null;
}
第二步:configureHeadlessProperty
Headless模式是系统的一种配置模式。在系统可能缺少显示设备、键盘或鼠标这些外设的情况下可以使用该模式。
这段代码具体什么用,不清楚。
第三步:SpringApplicationRunListeners
getRunListeners(args)方法:
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
还是熟悉的配方,使用getSpringFactoriesInstances方法,返回EventPublishingRunListener实例。
注意:在使用createSpringFactoriesInstances方法,根据构造方法实例化EventPublishingRunListener对象时,将SpringApplication中的listener添加到了EventPublishingRunListener中的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);
}
}
然后初始化SpringApplicationRunListeners对象:
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
}
listeners.starting()方法:
void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
此处的listeners只有一个:
public void starting() {
// 发送ApplicationStartingEvent
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
// SimpleApplicationEventMulticaster#multicastEvent
public void multicastEvent(ApplicationEvent event) {
this.multicastEvent(event, this.resolveDefaultEventType(event));
}
// multicastEvent
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 获取执行器,默认为null(这里可作为异步还是同步执行的扩展点)
Executor executor = getTaskExecutor();
// 遍历listener,进行回调
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
}
AbstractApplicationEventMulticaster#getApplicationListeners
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
// 此处source为:org.springframework.boot.context.event.ApplicationStartingEvent
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
// 构造cache
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
// cache中有则直接返回
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);
// 检索application listeners,指定了event 和source type.
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);
}
}
// retrieveApplicationListeners,实际的检索方法
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
//
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
// listenerBeans为空
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
// Add programmatically registered listeners, including ones coming
// from ApplicationListenerDetector (singleton beans and inner beans).
for (ApplicationListener<?> listener : listeners) {
//根据event和source type判断listener是否支持处理
//使用GenericApplicationListener接口中的boolean supportsEventType(ResolvableType eventType)方法
//和default boolean supportsSourceType(@Nullable Class<?> sourceType)
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.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()) {
//省略掉此处代码...
}
AnnotationAwareOrderComparator.sort(allListeners);
if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
retriever.applicationListeners.clear();
retriever.applicationListeners.addAll(allListeners);
}
return allListeners;
}
此处的allListeners有:
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
BackgroundPreinitializer
如果想要知道它们做了什么操作,只需要查看对应的onApplicationEvent方法即可。
LoggingApplicationListener:
private void onApplicationStartingEvent(ApplicationStartingEvent event) {
this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}
//get()
public static LoggingSystem get(ClassLoader classLoader) {
String loggingSystem = System.getProperty(SYSTEM_PROPERTY);
if (StringUtils.hasLength(loggingSystem)) {
if (NONE.equals(loggingSystem)) {
return new NoOpLoggingSystem();
}
return get(classLoader, loggingSystem);
}
//SYSTEMS变量在static块中初始化了
//返回loggingSystem为:LogbackLoggingSystem
return SYSTEMS.entrySet().stream().filter((entry) -> ClassUtils.isPresent(entry.getKey(), classLoader))
.map((entry) -> get(classLoader, entry.getValue())).findFirst()
.orElseThrow(() -> new IllegalStateException("No suitable logging system located"));
}
BackgroundPreinitializer,DelegatingApplicationListener来说,没有做任何事。(此处的event为org.springframework.boot.context.event.ApplicationStartingEvent,如果方法中做了instanceof判断,则可能不会走逻辑)
LiquibaseServiceLocatorApplicationListener:
public void onApplicationEvent(ApplicationStartingEvent event) {
// 当前场景不存在,liquibase.servicelocator.ServiceLocator,此方法也未执行
if (ClassUtils.isPresent("liquibase.servicelocator.CustomResolverServiceLocator",
event.getSpringApplication().getClassLoader())) {
new LiquibasePresent().replaceServiceLocator();
}
}
SimpleApplicationEventMulticaster#invokeListener
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
// 如果有错误处理,则在catch中调用了handleError方法
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
// doInvokeListener
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())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
最后
以上就是淡淡煎蛋为你收集整理的spring boot 源码学习2 - SpringApplication#run的全部内容,希望文章能够帮你解决spring boot 源码学习2 - SpringApplication#run所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复