关于spring:Spring-源码学习-14initApplicationEventMulticasteronRefresh

4次阅读

共计 4625 个字符,预计需要花费 12 分钟才能阅读完成。

前言

上一篇介绍了国际化的应用以及初始化音讯源的源码,接下来接着往下浏览,将进入 initApplicationEventMulticaster、onRefresh 和 registerListeners 的相干操作逻辑。

这一部分次要是初始化事件播送器以及注册监听器。而 onRefresh 局部则须要子类去实现。所以本文次要介绍以下几个局部:

  1. 什么是 Spring 事件?
  2. 监听器是如何应用的?

什么是 Spring 事件?

这块的介绍在官网 1.15.2. Standard and Custom Events 局部有介绍。

Spring 通过 ApplicationEvent 类和 ApplicationListener 接口提供 ApplicationContext 中的事件处理。如果将实现 ApplicationListener 接口的 bean 部署到上下文中,则每次将 ApplicationEvent 公布到 ApplicationContext 时,都会告诉该 bean。实质上,这是规范的观察者设计模式。

演绎下来次要就是三个局部: 事件、事件发布者、事件监听器。

  1. 事件:ApplicationEvent,要自定义事件,则须要创立一个类继承 ApplicationEvent。
  2. 事件发布者:ApplicationEventPublisher 和 ApplicationEventMulticaster,因为 ApplicationContext 实现了 ApplicationEventPublisher,所以事件公布能够间接应用 ApplicationContext。
  3. 事件监听器:ApplicationListener,通过创立一个实现了 ApplicationListener 并注册为 Spring bean 的类来接管音讯。

Spring 也提供了也有一些内置的监听器,能够在官网查看,这里就不做介绍了。

应用监听器

简略来说次要分为以下几个局部:

  1. 注册事件
  2. 注册监听器
  3. 公布事件

在接口调用公布事件时,监听器就会做出相应的操作。

1. 注册事件

创立 MyApplicationEvent 类并继承 ApplicationEvent

public class MyApplicationEvent extends ApplicationEvent {

    private static final long serialVersionUID = 5366526231219883438L;
    private String message;

    /**
     * Create a new {@code ApplicationEvent}.
     *
     * @param source the object on which the event initially occurred or with
     *               which the event is associated (never {@code null})
     */
    public MyApplicationEvent(Object source, String message) {super(source);
        this.message = message;
    }

    public String getMessage() {return message;}
}

2. 注册监听器

@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {

    @Override
    public void onApplicationEvent(MyApplicationEvent event) {System.out.println("MyApplicationListener 收到音讯:" + event.getMessage());

    }
}

当然这里也能够应用注解 @EventListener 的形式来应用。

@Component
public class MyAnnotationApplicationListener {@EventListener(classes = MyApplicationEvent.class)
    public void myApplicationEventListener(MyApplicationEvent event) {System.out.println("应用注解的形式, 收到事件:" + event.getMessage());
    }
}

3. 应用

因为 AnnotationConfigApplicationContext 实现了 ApplicationContext,而 ApplicationContext 实现了 ApplicationEventPublisher,所以这块传入以后 context 是没有问题的。

public class AnnotationConfigApplicationTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(JavaConfig.class);


        context.refresh();

        MyApplicationEvent myApplicationEvent = new MyApplicationEvent(context, "呼叫土豆, 呼叫土豆!");

        context.publishEvent(myApplicationEvent);

    }
}

日志输入:

源码局部

initApplicationEventMulticaster

这块和下面初始化音讯源相似,都是查找指定名称的 Bean,如果找不到,则本人应用默认的。

protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();

    // 是否蕴含 applicationEventMulticaster Bean
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        // 应用  SimpleApplicationEventMulticaster 创立一个 事件公布器
        SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
        this.applicationEventMulticaster = simpleApplicationEventMulticaster;
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'bean, using" +
                    "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

onRefresh

这块须要子类去实现,我这里通过断电,临时没有进去。所以就不介绍了。

registerListeners

protected void registerListeners() {
    // 增加实现 ApplicationListener 作为侦听器的 bean。// 不会影响其余侦听器,能够将它们增加为非 bean。// Register statically specified listeners first.
    // 先注册动态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    // 只是增加 并没有执行
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    // 公布晚期的工夫, 并且将 earlyApplicationEvents 设置为空
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

总结

这篇文章次要内容是介绍 Spring 事件的应用,同时简略介绍了 initApplicationEventMulticaster、onRefresh 和 registerListeners 局部的源码。

相干举荐

  • Spring 源码学习 13:initMessageSource
  • Spring 源码学习 12:registerBeanPostProcessors
  • Spring 源码学习 11:invokeBeanFactoryPostProcessors
正文完
 0