zoukankan      html  css  js  c++  java
  • Springboot listener

    在启动流程中,会出发许多ApplicationEvent。这时会调用对应的listener的onApplicationEvent方法。ApplicationEvent时观察者模式, 

    (1) 实体继承ApplicationEvent

    (2) 注入的Listener 实现接口ApplicationListener, 触发后的处理逻辑在onApplicationnEvent中

    (3) 事件发起方通过ApplicationContext 实例的publishEvent方法将 (1)的实体传入(2)

    SpringBoot 启动时的入口方法SpringApplication.run 内部实现为

        public static ConfigurableApplicationContext run(Class<?>[] primarySources,
                String[] args) {
            return new SpringApplication(primarySources).run(args);
        }

    第一步 new SpringApplication 内部会注入系统Listener  具体的listeners参见 https://blog.csdn.net/zl1zl2zl3/article/details/79765725

    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

    第二步 调用 run(args)  启动Listener

    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();

    第二步 2.1 如何获取监听器:在getRunListeners中会读取配置文件,加载的是Springboot META-INF/spring.factories 中的 org.springframework.boot.context.event.EventPublishingRunListener, 并生成"事件发布启动监听器"的工厂实例

    private SpringApplicationRunListeners getRunListeners(String[] args) {
        Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
        return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
                SpringApplicationRunListener.class, types, this, args));
    }
    
    private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
        return getSpringFactoriesInstances(type, new Class<?>[] {});
    }
    
    private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
            Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 使用Set确保的字符串的唯一性
        Set<String> names = new LinkedHashSet<String>(
                SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 1.载入工厂名称集合
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes,// 2.创建工厂实例
                classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);// 排序
        return instances;
    }

    META-INF/spring.factories

    # Run Listeners  这里呢,看这里!!!!
    org.springframework.boot.SpringApplicationRunListener=
    org.springframework.boot.context.event.EventPublishingRunListener

    第二步 2.2 启动监听 starting()

    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    //如果有监听器监听启动事件,则执行对应的动作
    listeners.starting();

    当前监听是EventPublishingRunListener,starting 方法如下

    public void starting() {
        this.initialMulticaster
                .multicastEvent(new ApplicationStartedEvent(this.application, this.args));
    }
    
    
    public void multicastEvent(ApplicationEvent event) {
        multicastEvent(event, resolveDefaultEventType(event));
    }
    
    public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {
                invokeListener(listener, event);
            }
        }
    }
  • 相关阅读:
    元音字母
    最近使用LINQ遇到的故障
    ASP.NET 2.0下实现匿名用户向注册用户的迁移(下)
    ASP.NET MVC 2配置使用CKEditor编辑器
    ASP.NET 角色及成员管理(entry 'AspNetSqlMembershipProvider' has already been added错误的解决)
    为什么Firefox 3及之后的版本不能加载本地的JavaScript文件了?
    在ASP.NET MVC中使用DropDownList
    LINQ entityset 不包含GetEnumerator的定义,在MVC中使用entity framework(EF)出现“必须添加对程序集“System.Data.Entity”解决方法
    去除element.style样式
    判断ViewData[""]是否为空
  • 原文地址:https://www.cnblogs.com/webglcn/p/10659466.html
Copyright © 2011-2022 走看看