***的使用

  1. 定义事件
public class DemoEvent extends ApplicationEvent {
   
    private String name;

    public DemoEvent(Object source, String name) {
   
        super(source);
        this.name = name;
    }

    public String getName() {
   
        return name;
    }

    public void setName(String name) {
   
        this.name = name;
    }
}
  1. ***
  • 方式一:接口实现***:
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
   
    @Override
    public void onApplicationEvent(DemoEvent event) {
   
        System.out.println("事件"+event.getName()+"接口触发!");
    }
}
  • 方式二:注解***:
@Component
public class DemoAnnotationListener {
   
    @EventListener
    public void onEvent(DemoEvent event) {
   
        System.out.println("事件"+event.getName()+"注解触发!");
    }
}
  1. 发布事件
@SpringBootApplication
public class DemoApplication {
   
	public static void main(String[] args) {
   
		ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
		run.publishEvent(new DemoEvent(run,"发布"));
	}
}

***源码解析

***是观察者设计模式的实现。
在refresh()方发中调用了prepareRefresh()方法,预刷新上下文环境。

  1. 看下prepareRefresh()方法:
protected void prepareRefresh() {
   
		/** * 创建一个早期事件***对象集合 */
		if (this.earlyApplicationListeners == null) {
   
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
   
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		/** * 创建一个容器用于保存早期待发布的事件集合 * 什么是早期事件? * 就是我们的事件***还没有注册到多播器上的时候都称为早期事件 * 早期事件不需要手动publishEvent发布, 在registerListeners中会自动发布, 发布完早期事件就不存在了。 */
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
  1. 创建事件多播器
    initApplicationEventMulticaster()方法:
protected void initApplicationEventMulticaster() {
   
		//获取我们的bean工厂对象
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//判断容器中是没有有我们的applicationEventMulticaster 应用多播器组件
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
   
			//直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isDebugEnabled()) {
   
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		//容器中没有的话
		else {
   
			//spring ioc显示的new 一个SimpleApplicationEventMulticaster对象保存在applicatoinContext对象中
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			//并且注入到容器中
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
   
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}

AbstractApplicationEventMulticaster有属性ListenerRetriever,存储了所有的listener。

applicationListenerBeans只存储了***的名字,主要是为了捕获懒加载的***。
多播器负责存储***和后面广播事件。

  1. 注册*** registerListeners()

    以上三步整个***就注册完成了。

看下发布事件的流程:

自定义多播器

自定义多播器可以选择监听事件是否异步执行。

@Configuration
@ComponentScan(basePackages = {
   "com.tuling.event"})
@EnableAsync
public class MainConfig {
   
	/* 往SimpleApplicationEventMulticaster设置taskExecutor则为异步事件 或者使用@Async */
    @Bean(name = "applicationEventMulticaster")
    public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
   
        SimpleApplicationEventMulticaster eventMulticaster
                = new SimpleApplicationEventMulticaster();
        eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
        return eventMulticaster;
    }
}