springboot mvc 项目启动过程探究2--spring框架的观察者模式

上一篇博客写了SpringApplication.run(AuthServiceApplication.class, args); 的SpringApplication初始化,这一篇就写一下后面的run方法。

前言:写本篇博客前,我自己一步步的点进方法去看代码,乱糟糟的也不知道,代码都在做什么,反过来调过去的看了许久之后,发现,要想看懂SpringApplication的框架,首先最应该先了解的是 观察者模式,因为,在我的理解和查看中,又查阅不少博客,发现框架整体是用观察者来加载各个组件,达到灵活插拔的效果。观察者模式,请不太清楚的同学自行查阅,我这里给出简单的例子,就不再多做解释。

 1 public class BaseEvent extends EventObject {
 2     String name;
 3 
 4     public BaseEvent(Object source, String name) {
 5         super(source);
 6         this.name = name;
 7     }
 8 
 9     public String getName() {
10         return name;
11     }
12 }
13 
14 public interface BaseListener<T extends BaseEvent> extends EventListener {
15     void doEvent(T t);
16 }
17 public interface EventPublisher<T extends BaseEvent> {
18     abstract void publish(T event);
19 }
20 public class Event extends BaseEvent {
21     public Event(Object source, String name) {
22         super(source, name);
23     }
24 }
25 public class Listener implements BaseListener<Event> {
26 
27     private String name;
28 
29     public Listener(String name) {
30         this.name = name;
31     }
32     public Listener() {
33     }
34     @Override
35     public void doEvent(Event event) {
36         System.out.println("我是监听者:"+this.name+",我监控到来自:"+ event.getName()+",的event");
37     }
38 
39 }
40 public class BaseEventPublisher<T extends BaseEvent> implements EventPublisher {
41 
42     List<BaseListener<T>> listenerList = new ArrayList<>();
43 
44     public List<BaseListener<T>> getListenerList() {
45         return listenerList;
46     }
47 
48     @Override
49     public void publish(BaseEvent event) {
50         if (!CollectionUtils.isEmpty(listenerList)) {
51             for (BaseListener listener:listenerList) {
52                 listener.doEvent((T) event);
53             }
54         }
55     }
56 }
57 
58 
59     BaseEvent eventA = new Event("","eventA");
60         BaseEventPublisher publisher = new BaseEventPublisher();
61         BaseListener<Event> listenerA = new Listener("listenerA");
62         BaseListener<Event> listenerB = new Listener("listenerB");
63         publisher.getListenerList().add(listenerA);
64         publisher.getListenerList().add(listenerB);
65         publisher.publish(eventA);

 

大家可以自行运行一下,理解一下观察者模式的思维。

 --------------------

下面就写一下我自己看源码的理解

 1 public ConfigurableApplicationContext run(String... args) {
 2         StopWatch stopWatch = new StopWatch();//用来输出所包含的代码运行完消耗的时间,可自行查阅相关用法,不再此赘述
 3         stopWatch.start();
 4         ConfigurableApplicationContext context = null;
 5         Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
 6         configureHeadlessProperty();
 7         SpringApplicationRunListeners listeners = getRunListeners(args);//获取上面博客所述的配置在spring.factories的监听者
 8         listeners.starting();//这里就开始了观察者模式
 9         try {
10             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
11             ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);//准备运行的环境信息
12             configureIgnoreBeanInfo(environment);//配置忽略
13             Banner printedBanner = printBanner(environment);
14             context = createApplicationContext();//创建上下文
15             exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
16                     new Class[] { ConfigurableApplicationContext.class }, context);
17             prepareContext(context, environment, listeners, applicationArguments, printedBanner);//准备上下文
18             refreshContext(context);//刷新上下文
19             afterRefresh(context, applicationArguments);
20             stopWatch.stop();
21             if (this.logStartupInfo) {
22                 new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
23             }
24             listeners.started(context);//启动上下文
25             callRunners(context, applicationArguments);//通知所有的线程开始运行
26         }
27         catch (Throwable ex) {
28             handleRunFailure(context, ex, exceptionReporters, listeners);
29             throw new IllegalStateException(ex);
30         }
31 
32         try {
33             listeners.running(context);//运行
34         }
35         catch (Throwable ex) {
36             handleRunFailure(context, ex, exceptionReporters, null);
37             throw new IllegalStateException(ex);
38         }
39         return context;
40     }

 上面代码段,先着重讲一下第八行,listeners.starting();因为后面很多代码内部都和这一行运行的代码类似

    void starting() {
        for (SpringApplicationRunListener listener : this.listeners) {
            listener.starting();
        }
    }
1     public void starting() {
2         this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
3     }
initialMulticaster,多路广播器。通知所有监听者,接到广播的就要运行了。multicastEvent代码如下
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);
}
}
}

下面进入invokeListener

 1 private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
 2         try {
 3             listener.onApplicationEvent(event);//划重点
 4         }
 5         catch (ClassCastException ex) {
 6             String msg = ex.getMessage();
 7             if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
 8                 // Possibly a lambda-defined listener which we could not resolve the generic event type for
 9                 // -> let's suppress the exception and just log a debug message.
10                 Log logger = LogFactory.getLog(getClass());
11                 if (logger.isTraceEnabled()) {
12                     logger.trace("Non-matching event type for listener: " + listener, ex);
13                 }
14             }
15             else {
16                 throw ex;
17             }
18         }
19     }
 listener.onApplicationEvent(event);此方法运行实现了 org.springframework.context.ApplicationListener类的onApplicationEvent方法。

整个框架多处使用,广播和监听机制,*的配置监听者。各个组件,配置自己的监听者,达到*扩展的目的。

 

上一篇:JavaWeb之Filter过滤器和Listener监听器


下一篇:event