案例
监听器模式要素
1.事件
public abstract class WeatherEvent {
public abstract String getWeather();
}
public class SnowEvent extends WeatherEvent {
@Override
public String getWeather() {
return "snow";
}
}
public class RainEvent extends WeatherEvent {
@Override
public String getWeather() {
return "rain";
}
}
2.监听器
public interface WeatherListener{
void onWeatherEvent(WeatherEvent event);
}
public class RainListener implements WeatherListener {
@Override
public void onWeatherEvent(WeatherEvent event) {
if (event instanceof RainEvent){
System.out.println("hello "+event.getWeather());
}
}
}
3.广播器
public interface EventMulticaster {
//广播事件
void multicastEvent(WeatherEvent event);
//添加监听者
void addListener(WeatherListener weatherListener);
//移除监听者
void removeListener(WeatherListener weatherListener);
}
public class WeatherEventMulticaster implements EventMulticaster {
private List<WeatherListener> listeners = new ArrayList<>();
@Override
public void multicastEvent(WeatherEvent event) {
listeners.forEach(i -> i.onWeatherEvent(event));
}
@Override
public void addListener(WeatherListener weatherListener) {
listeners.add(weatherListener);
}
@Override
public void removeListener(WeatherListener weatherListener) {
listeners.remove(weatherListener);
}
}
4.触发机制
public class TestWeather {
public static void main(String[] args) {
WeatherEventMulticaster eventMulticaster = new WeatherEventMulticaster();
RainListener rainListener = new RainListener();
eventMulticaster.addListener(rainListener);
eventMulticaster.addListener(new RainListener());
eventMulticaster.addListener(new SnowListener());
//eventMulticaster.multicastEvent(new SnowEvent());
eventMulticaster.removeListener(rainListener);
eventMulticaster.multicastEvent(new RainEvent());
}
源码分析
"META-INF/spring.factories ----> springboot框架中
监听器
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
public interface ApplicationEventMulticaster {
/**
* Add a listener to be notified of all events.
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* Add a listener bean to be notified of all events.
* @param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* Remove a listener from the notification list.
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
* Remove a listener bean from the notification list.
* @param listenerBeanName the name of the listener bean to remove
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* Remove all listeners registered with this multicaster.
* <p>After a remove call, the multicaster will perform no action
* on event notification until new listeners are registered.
*/
void removeAllListeners();
/**
* Multicast the given application event to appropriate listeners.
* <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}
* if possible as it provides better support for generics-based events.
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
/**
* Multicast the given application event to appropriate listeners.
* <p>If the {@code eventType} is {@code null}, a default type is built
* based on the {@code event} instance.
* @param event the event to multicast
* @param eventType the type of event (can be {@code null})
* @since 4.2
*/
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
只会针对感兴趣的lister过滤 然后在发布通知。
监听器的源码分析
isAssignableFrom
A.isAssignableFrom(b) 意思是b是不是a的子类或者子接口
object.isAssignableFrom(b) true object 是所有类的父类
class A{}
class B extends A{}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
A ba = new B();
System.out.println("1--------");
System.out.println(A.class.isAssignableFrom(a.getClass()));
System.out.println(B.class.isAssignableFrom(b.getClass()));
System.out.println(A.class.isAssignableFrom(b.getClass()));
System.out.println(B.class.isAssignableFrom(a.getClass()));
System.out.println(A.class.isAssignableFrom(ba.getClass()));
System.out.println(B.class.isAssignableFrom(ba.getClass()));
System.out.println(Object.class.isAssignableFrom(ba.getClass()));
}
}
自定义监听器
第一种方式
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
@Order(1)
public class FirstListener implements ApplicationListener<ApplicationStartingEvent> {
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
System.out.println("firstListener");
}
}
在配置文件进行配置
org.springframework.context.ApplicationListener=xxxx.xxxx.xxx.FirstListener
第二方式 和第三种方式和以前的初始化器一致。
第四种
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
public class FourthListener implements SmartApplicationListener {
//关注的事件类型
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationStartedEvent.class.isAssignableFrom(eventType) || ApplicationPreparedEvent.class.isAssignableFrom(eventType);
}
// 回调方法
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("hello fourth");
}
}
多监听器,可以多个事件。注册方式可以和其他三个一样。