spring提供了publish-event-listener机制还有异步任务机制,能很好的帮助我们解耦我们的应用跟代码的管理。
config类
@Configuration
@ComponentScan("。。。")
blic class AppletApiConfigure {
}
事件类,必须实现ApplicationEvent
public class MyEvent extends ApplicationEvent {
public MyEvent() {
super();
}
}
观察者,必须实现ApplicationListener,并指定泛型为我们的自定义事件
@Component
public class MyListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
System.out.println(event.getMsg());
}
}
发布者,直接用我们的上下文对象进行发布,它继承了ApplicationEventPublisher
@Component
public class MyPublisher {
@Autowired
private ApplicationContext applicationContext;
public void publish() {
applicationContext.publishEvent(new MyEvent());
}
}
相关源代码
package org.springframework.context;
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
追踪到
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
。。。
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
}
主要是
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
getApplicationEventMulticaster()
/**
* Return the internal ApplicationEventMulticaster used by the context.
* @return the internal ApplicationEventMulticaster (never {@code null})
* @throws IllegalStateException if the context has not been initialized yet
*/
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}
它其实就是返回当前类持有的ApplicationEventMulticaster这个接口的实现的引用,管理了我们的listener,并且可以向它们发布事件。
getApplicationEventMulticaster()返回的其实一个发布者,我们的容器applicationContext其实就是调用这个对象去发布事件
并且它管理了我们所有的listener。
multicastEvent(…)
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
getApplicationListeners(event, type),其实就是返回了当前对象所管理的监听了当前事件的listener,之后在调用listener的invokeListener(listener, event)方法。
invokeListener(…)
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);
}
}
doInvokeListener(listener, event);就是我们实现了applicationListener接口所实现的方法,整个过程是同步的
注解实现
@Component
public class MyListener{
@EventListener
public void onApplicationEvent(MyEvent event) {
System.out.println(event.getMsg());
}
@EventListener
public void onApplicationEvent(MySecondEvent event) {
System.out.println(event.getMsg());
} }
异步实现
自定义一个ApplicationEventMulticaster
//需要注意的是,我们的名字一定要叫applicationEventMulticaster,否则不生效,回头看下源码就明白了
@Component("applicationEventMulticaster")
public class MyMulticaster extends SimpleApplicationEventMulticaster {
@Override
protected Executor getTaskExecutor() {
// 这里可以按实际需求进行线程池的配置
return new SimpleAsyncTaskExecutor();
}
/**
* 这个方法主要配置错误处理,默认只会打一个警告级别的日志
*
* @return
*/
@Override
protected ErrorHandler getErrorHandler() {
return (t -> {
System.out.println("出错了");
});
}
}
配置类上加注解@EnableAsync
方法上加@Async可以是部分方法异步执行