盘点 SpringBoot : Listener

2,414 阅读9分钟

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…

一 .前言

本篇文档来完善 Spring 体系中 Listener 的相关概念 :

主要内容 :

  • Listener 的处理流程
  • Listener 的同步和异步处理
  • 常见的 Listener 处理

Spring-listener.jpg

二 . Listener 的基础使用

基础使用中包括四个步骤 :

  • 构建一个 TranTO 用于承载数据
  • 构建一个 Event 用于发布
  • 构建一个 Listener 接受事件及处理
  • 主业务中发布事件

2.1 数据承载体

数据承载体用于在发布事件的同事携带数据给 Listener

public class ListenerTranTO {

    private String eventName;

    private Map<String, String> eventInfo;

    public String getEventName() {
        return eventName;
    }

    public void setEventName(String eventName) {
        this.eventName = eventName;
    }

    public Map<String, String> getEventInfo() {
        return eventInfo;
    }

    public void setEventInfo(Map<String, String> eventInfo) {
        this.eventInfo = eventInfo;
    }


    @Override
    public String toString() {
        return "ListenerTranTO{" +
                "eventName='" + eventName + '\'' +
                ", eventInfo=" + eventInfo +
                '}';
    }
}

2.2 构建发布 Event

可以看到 , Event 是基于 ApplicationEvent 构建了一个对象

  public class DefaultEvent extends ApplicationEvent {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public DefaultEvent(ListenerTranTO tranTO) {
        super(tranTO);
    }
}

2.3 构建一个 Listener 接受事件及处理

@Component
public class DefaultListener implements ApplicationListener<DefaultEvent> {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void onApplicationEvent(DefaultEvent event) {
        logger.info("------> DefaultEvent Listner , Properties [{}] <-------", String.valueOf(event.getSource()));
    }
}

2.4 主业务中发布事件

 @Autowired
    private ApplicationContext context;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        logger.info("------> Default Event Publish Start >>>>>  <-------");

        ListenerTranTO tranTO = new ListenerTranTO();

        Map<String, String> infoMap = new HashMap<>();
        infoMap.put("info", "This is in Info");
        infoMap.put("message", "Listener Success");

        tranTO.setEventInfo(infoMap);
        tranTO.setEventName("DefaultListener");

        context.publishEvent(new DefaultEvent(tranTO));

        logger.info("------> Default Event Publish End >>>>> [{}]  <-------", tranTO.toString());
    }
}

三 . Listener 流程解析

这部分主要是说明 Listener 在 整个体系中的运用 , 先来看一下常见的几个 Listener , 首先看一下官方对 ApplicationListener 的定义 : 由应用程序事件侦听器实现的接口 , 基于观察者设计模式的标准java.util.EventListener接口。

这里回顾一下 观察者模式 的相关概念 :

观察者模式意图 : 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

参考 @ blog.csdn.net/zzg19950824…

image.png

public interface Observer {  
    public void update();  
}  
//两个实现类:

public class Observer1 implements Observer {  
  
    @Override  
    public void update() {  
        System.out.println("observer1 has received!");  
    }  
}  

public class Observer2 implements Observer {  
  
    @Override  
    public void update() {  
        System.out.println("observer2 has received!");  
    }  
  
}  
//Subject接口及实现类:

public interface Subject {  
      
    /*增加观察者*/  
    public void add(Observer observer);  
      
    /*删除观察者*/  
    public void del(Observer observer);  
      
    /*通知所有的观察者*/  
    public void notifyObservers();  
      
    /*自身的操作*/  
    public void operation();  
}  

public abstract class AbstractSubject implements Subject {  
  
    private Vector<Observer> vector = new Vector<Observer>();  
    @Override  
    public void add(Observer observer) {  
        vector.add(observer);  
    }  
  
    @Override  
    public void del(Observer observer) {  
        vector.remove(observer);  
    }  
  
    @Override  
    public void notifyObservers() {  
        Enumeration<Observer> enumo = vector.elements();  
        while(enumo.hasMoreElements()){  
            enumo.nextElement().update();  
        }  
    }  
}  

public class MySubject extends AbstractSubject {  
  
    @Override  
    public void operation() {  
        System.out.println("update self!");  
        notifyObservers();  
    }  
  
}  

//测试类:

public class ObserverTest {  
  
    public static void main(String[] args) {  
        Subject sub = new MySubject();  
        sub.add(new Observer1());  
        sub.add(new Observer2());  
          
        sub.operation();  
    }  
  
}  
//输出:
update self!
observer1 has received!
observer2 has received!

3.1 Listener 的触发方式

Listerner的触发主要有以下几种 :

  • 容器启动时自动触发
  • 手动发布 publishEvent

类型一 : 容器自动触发 , 触发流程

C- AbstractApplicationContext # refresh()

其中大部分是在这个流程中完成触发 , 通常都是通过 publish 进行发布
this.applicationContext.publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));    
C50- AbstractApplicationContext
    M50_10- publishEvent(ApplicationEvent event)
    M50_11- publishEvent(Object event, @Nullable ResolvableType eventType)
    
// Step 1 : 发布 Event 事件
public void publishEvent(ApplicationEvent event) {
    publishEvent(event, null);
}


protected void publishEvent(Object event, @Nullable ResolvableType eventType) {

    // Decorate event as an ApplicationEvent if necessary
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    } else {
        // 此处如果不是 ApplicationEvent , 则构建 PayloadApplicationEvent -> PS:M50_11_01
        applicationEvent = new PayloadApplicationEvent<>(this, event);
        if (eventType == null) {
            // 此处获取事件内 Object 类型
            eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
        }
    }

    // 如果可能,立即进行多播,或者在多播器初始化后延迟多播 -> PS:M50_11_02
    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    } else {
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // 也可以通过父上下文发布事件
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        }else {
            this.parent.publishEvent(event);
        }
    }
}


// PS:M50_11_01 PayloadApplicationEvent 是什么 ? 
C- PayloadApplicationEvent
    ?- 携带任意有效负载的ApplicationEvent
	I- ResolvableTypeProvider
	F- private final T payload;
	M- getResolvableType() : 返回描述此实例的ResolvableType
            - return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
    

PS:M50_11_02 Listener 的 多播是什么?

Listener 的 多播是什么 ?

将所有事件多播给所有注册的侦听器,让侦听器忽略它们不感兴趣的事件. 监听器通常会对传入的事件对象执行相应的instanceof检查。

同时 , 可以异步处理 , 指定一个替代任务执行器,使侦听器在不同的线程中执行,例如在线程池中执行

总结 : 可以把其当成Listener 的主要发布者


// Step 1 : 事件多播的发布方式
if (this.earlyApplicationEvents != null) {
    this.earlyApplicationEvents.add(applicationEvent);
} else {
    getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}


// Step 2 : 对象的创建地方
C- AbstractApplicationContext
    F- Set<ApplicationEvent> earlyApplicationEvents : 在多播器设置之前发布的ApplicationEvents
        
// 事件的多播器创建的地方是在 AbstractApplicationContext : 
C- AbstractApplicationContext
    M- refush
        - initApplicationEventMulticaster()

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 如果 APPLICATION_EVENT_MULTICASTER_BEAN_NAME (applicationEventMulticaster) 中存在 , 则直接从Bean 工厂获取
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    } else {
        // 构建一个新 SimpleApplicationEventMulticaster , 并且注册
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}


// Step 3 : 来看一下 earlyApplicationEvents 的使用
C- AbstractApplicationContext
protected void registerListeners() {
        // 首先注册静态指定的侦听器
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        //  获得所有的 ApplicationListener , 此处会根据 type 获取所有的 ApplicationListener
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            // 往 ApplicationEventMulticaster 中添加 Listener 
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 发布早期应用事件
        // 此处首先获取原本的 earlyEventsToProcess 对象 , 用于缓存 ,同时清空之前的镀锡
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
}

// 可以看到 , 最后仍然会调用 multicastEvent 进行消息的发布


3.2 Listener 的循环处理

此处调用 multicastEvent 进行最后的操作 , 主要有几个步骤 :

  • resolveDefaultEventType 获得 事件的类型
  • getTaskExecutor 获得 Executor -> PS:M50_12_1
  • 获得所有的 Listenr
// Step 2 : 循环所有的 Listener 
C50- AbstractApplicationContext
    M50_12- multicastEvent(ApplicationEvent event)
    	- getApplicationListeners 获取所有的 Listeners  -> M50_12_01

/**
* 循环 Listener 
**/
C- SimpleApplicationEventMulticaster
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    
    // 获取 Listener 对象
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        }else {
            invokeListener(listener, event);
        }
    }
}


// PS : ApplicationEventMulticaster 接口 , 主要实现类是 SimpleApplicationEventMulticaster
C- ApplicationEventMulticaster
    M- void addApplicationListener(ApplicationListener<?> listener) : 添加一个侦听器,用于通知所有事
    M- void addApplicationListenerBean(String listenerBeanName) : 添加一个侦听器bean,用于通知所有事件
    M- void removeApplicationListener(ApplicationListener<?> listener) : 从通知列表中删除侦听器
    M- void removeApplicationListenerBean(String listenerBeanName) : 从通知列表中删除侦听器bean
    M- void removeAllListeners() : 删除所有注册到这个多播广播的监听器 
    M- void multicastEvent(ApplicationEvent event) : 将给定的应用程序事件组播到适当的侦听器
    M- void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) : 将给定的应用程序事件组播到适当的侦听器


// PS : 补充 SimpleApplicationEventMulticaster 详见下文


以下通过 eventType 获得 ApplicationListener 类

C- AbstractApplicationEventMulticaster
// M50_12_01 getApplicationListeners 主流程
protected Collection<ApplicationListener<?>> getApplicationListeners(
            ApplicationEvent event, ResolvableType eventType) {

    Object source = event.getSource();
    Class<?> sourceType = (source != null ? source.getClass() : null);
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

    // 快速检查ConcurrentHashMap上的现有条目...
    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
    if (retriever != null) {
            return retriever.getApplicationListeners();
    }

    if (this.beanClassLoader == null ||(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
                        (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
        // listener检索器的完全同步构建和缓存
        synchronized (this.retrievalMutex) {
            retriever = this.retrieverCache.get(cacheKey);
            if (retriever != null) {
                return retriever.getApplicationListeners();
            }
            retriever = new ListenerRetriever(true);
            // 获取 ApplicationListener 集合
            Collection<ApplicationListener<?>> listeners =retrieveApplicationListeners(eventType, sourceType, retriever);
            this.retrieverCache.put(cacheKey, retriever);
            return listeners;
        }
    } else {
        // 没有监听检索缓存 则 没有必要同步
        return retrieveApplicationListeners(eventType, sourceType, null);
    }
}


C- AbstractApplicationContext
// 实际检索给定事件和源类型的应用程序监听器
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
            ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {

        List<ApplicationListener<?>> allListeners = new ArrayList<>();
        Set<ApplicationListener<?>> listeners;
        Set<String> listenerBeans;
        
        // 通常为 ListenerRetriever , 这是一个Helper类,它封装一组特定的目标侦听器,允许高效检索预筛选的侦听器
        // 每个事件类型和源类型都会缓存此Helper类的实例
        synchronized (this.retrievalMutex) {
            // 获得 Listener 对象
            listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
            listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
        }

        // 添加以编程方式注册的侦听器,包括来自ApplicationListenerDetector的侦听器(单例bean和内部bean)ans).
        for (ApplicationListener<?> listener : listeners) {
            // 判断是否支持该 Event 
            if (supportsEvent(listener, eventType, sourceType)) {
                if (retriever != null) {
                    retriever.applicationListeners.add(listener);
                }
                allListeners.add(listener);
            }
        }

        // 按bean名添加侦听器,可能与上面以编程方式注册的侦听器重叠
        if (!listenerBeans.isEmpty()) {
                
            // 因为此处时Bean 名称 , 所以需要通过BeanFactory 构建    
            ConfigurableBeanFactory beanFactory = getBeanFactory();
            
            for (String listenerBeanName : listenerBeans) {
                try {
                      // 校验是否支持当前 Event
                    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)) {
                                    retriever.applicationListeners.add(listener);
                                }
                                else {
                                    retriever.applicationListenerBeans.add(listenerBeanName);
                                }
                            }
                            allListeners.add(listener);
                        }
                    }
                    else {
                        Object listener = beanFactory.getSingleton(listenerBeanName);
                        if (retriever != null) {
                            retriever.applicationListeners.remove(listener);
                        }
                        allListeners.remove(listener);
                    }
                }
                catch (NoSuchBeanDefinitionException ex) {
                }
            }
        }
        
        // 对 allListeners 进行排序
        AnnotationAwareOrderComparator.sort(allListeners);
        if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
            retriever.applicationListeners.clear();
            retriever.applicationListeners.addAll(allListeners);
        }
        return allListeners;
    }
    

// 获取 Listener 
C- AbstractApplicationEventMulticaster
    // Helper类,它封装一组特定的目标Listener,允许高效检索预筛选的Listener
    PVC- ListenerRetriever
        F- Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>()
        F- Set<String> applicationListenerBeans = new LinkedHashSet<>()
    

PS:M50_12_1 : getTaskExecutor 获取 Executor

返回此多播器的当前任务执行器

3.3 Invoke 代理

此处进行实际的调用


C- SimpleApplicationEventMulticaster
    M- invokeListener(ApplicationListener<?> listener, ApplicationEvent event) 
        - 获取 ErrorHandler
        - doInvokeListener 代理 Listener
        - 如果出现异常 , errorHandler.handleError(err)
    M- doInvokeListener(ApplicationListener listener, ApplicationEvent event)
        - listener.onApplicationEvent(event) 发起Event 处理



// Step 3 : invoke Listener 类
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);
    }
}

// Event 处理
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
	listener.onApplicationEvent(event);
} 
    

补充 存放 Listener 的时机


//存在四个地方往 Set 中添加 Listener 对象

C- AbstractApplicationEventMulticaster # addApplicationListener(ApplicationListener<?> listener)
    ?- 手动添加 Listener , 具体哪些地方会调用就不详细说了
C- AbstractApplicationEventMulticaster # retrieveApplicationListeners
    ?- 这里是从 defaultRetriever 添加到传入的 ListenerRetriever 中

四. SpringListener 异步处理

在不开启异步的情况下 , Listener 是非异步的

@Configuration
@EnableAsync
public class AsyncListenerConfiguration implements AsyncConfigurer {

    /**
     * Spring Async 配置信息
     *
     * @return
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 设置线程池的数目
        threadPoolTaskExecutor.setCorePoolSize(10);
        threadPoolTaskExecutor.setMaxPoolSize(20);
        threadPoolTaskExecutor.setQueueCapacity(50);
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

/**
* 异步监听
**/
@Component
public class AsyncListener {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 此处使用 Async 异步处理
     *
     * @param defaultEvent
     */
    @Async
    @EventListener
    public void doAsyncEvent(DefaultEvent defaultEvent) {
        logger.info("------> 通过异步监听 :[{}] , Thread is :[{}]<-------", defaultEvent.getSource(), Thread.currentThread().getId());
    }

}


// 发布事件 
context.publishEvent(new DefaultEvent(tranTO));
try {
    Thread.sleep(10000);
} catch (InterruptedException e) {
    e.printStackTrace();
}



2021-05-31 15:02:53.284  INFO 23640 --- [           main] c.g.s.s.demo.listener.DefaultListener    : ------> DefaultEvent Listner , Properties [ListenerTranTO{eventName='DefaultListener', eventInfo={message=Listener Success, info=This is in Info}}] <-------
2021-05-31 15:02:53.287  INFO 23640 --- [           main] c.g.s.s.demo.listener.DefaultListener    : ------> Listener Thread 情况 :[1] <-------
2021-05-31 15:02:53.297  INFO 23640 --- [lTaskExecutor-1] c.g.s.s.demo.listener.AsyncListener      : ------> 通过异步监听 :[ListenerTranTO{eventName='DefaultListener', eventInfo={message=Listener Success, info=This is in Info}}] , Thread is :[330]<-------
2021-05-31 15:03:03.288  INFO 23640 --- [           main] c.g.s.source.demo.listener.TestListener  : ------> Default Event Publish End >>>>> [ListenerTranTO{eventName='DefaultListener', eventInfo={message=Listener Success, info=This is in Info}}]  -- [1] <-------



// 可以看到 , 此处发布后 , 同步监听停了10秒 ,而异步监听成功处理
    
// 原理 : 
AsyncExecutionInterceptor : 主要是方法进行了异步代理

总结

这文章完善了 Spring 体系中的 Listener 模块 , 总体可以分为2种情况 :

同步情况 : AbstractApplicationContext 中循环所有的 Listener 进行处理
异步情况 : 首先对方法进行代理 ,在调用时 ,通过 Async 配置的线程池中开启一个新线程进行处理

附录

# Listener 的注册方式

转载自 @ www.cnblogs.com/linlf03/p/1…

方式一 : spring.factories 中配置监听器

/

public class FirstListener  implements ApplicationListener<ApplicationStartedEvent> {
 
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("hello, first listener");
    }
}

// 在spring.factories文件中增加配置监听器
// 原理可以看看这一篇文章 : https://juejin.cn/post/6955489109225930789

org.springframework.context.ApplicationListener=com.example.demo.listener.FirstListener

方式二 : Main 函数中添加 Listener

public static void main(String[] args) {
         
    SpringApplication springApplication = new SpringApplication(Sb2Application.class);
    springApplication.addListeners(new SecondListener());
    springApplication.run(args);
}

方式三 : application.propeties 文件中配置


context.listener.classes=....listener.class

方式四 : 相关模块中添加 listener

在部分场景中 , 可以往 Web 容器中通过 AddListener 的方式添加

  • JPA 的 @EntityListeners

方式五 : 注解添加

@EventListener
public void event(Object event){
    System.out.println("MyEventHandle 接收到事件:" + event.getClass());
}

方式五 : WebListener

@WebListener
public class DefaultHttpSessionListener implements HttpSessionListener {
    //...........
}

// PS : Application 方法上需要标注注解 @ServletComponentScan


# WebListener 使用 (与此相同的还有 ServletContextListener )

这里说一下 WebListener 的使用方式 , HttpSessionListener 也是 EventListener 的子接口之一 , 通过实现该 Listener 可以实现对 Session 的操作

@WebListener
public class DefaultHttpSessionListener implements HttpSessionListener {

    private static final Logger LOG = LoggerFactory.getLogger(DefaultHttpSessionListener.class);

    private final AtomicInteger counter = new AtomicInteger();

    @Override
    public void sessionCreated(HttpSessionEvent se) {

        LOG.info("New session is created. Adding Session to the counter.");
        counter.incrementAndGet();  //incrementing the counter
        updateSessionCounter(se);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        LOG.info("Session destroyed. Removing the Session from the counter.");
        counter.decrementAndGet();  //decrementing counter
        updateSessionCounter(se);
    }

    private void updateSessionCounter(HttpSessionEvent httpSessionEvent) {
        //Let's set in the context
        httpSessionEvent.getSession().getServletContext()
                .setAttribute("activeSession", counter.get());
        LOG.info("Total active session are {} ", counter.get());
    }
}

// PS : Application 方法上需要标注注解 @ServletComponentScan

该方案的实现实现流程 : 

 public void tellNew() {

        // Notify interested session event listeners
        fireSessionEvent(Session.SESSION_CREATED_EVENT, null);

        // Notify interested application event listeners
        Context context = manager.getContext();
        Object listeners[] = context.getApplicationLifecycleListeners();
        if (listeners != null && listeners.length > 0) {
            HttpSessionEvent event =
                new HttpSessionEvent(getSession());
            for (int i = 0; i < listeners.length; i++) {
                if (!(listeners[i] instanceof HttpSessionListener))
                    continue;
                HttpSessionListener listener =
                    (HttpSessionListener) listeners[i];
                try {
                    context.fireContainerEvent("beforeSessionCreated",
                            listener);
                    listener.sessionCreated(event);
                    context.fireContainerEvent("afterSessionCreated", listener);
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    try {
                        context.fireContainerEvent("afterSessionCreated",
                                listener);
                    } catch (Exception e) {
                        // Ignore
                    }
                    manager.getContext().getLogger().error
                        (sm.getString("standardSession.sessionEvent"), t);
                }
            }
        }

}

// Context 的处理逻辑
ServletListenerRegistrationBean 中进行注册

更新日志 :

  • V20210804 : 补充流程图