观察者模式在Spring中的应用
2019-07-16 23:16
676 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/CoffeeAndMilk123/article/details/96200357
观察者模式在Spring中的主要体现在事件监听,事件机制的实现需要三个部分,事件源,事件,事件监听器;
1 ApplicationEvent抽象类作为事件的父类,通过source获取事件源。
public abstract class ApplicationEvent extends EventObject { private static final long serialVersionUID = 7099057708183571937L; private final long timestamp = System.currentTimeMillis(); public ApplicationEvent(Object source) { super(source); } public final long getTimestamp() { return this.timestamp; } }
2 ApplicationListener接口作为事件监听器,继承自EventListener
@FunctionalInterface public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E event); }
3 ApplicationContext接口作为事件源,在这里可以将监听器注册进应用上下文中,也可以触发指定的事件。在ApplicationContext的父类ApplicationEventPublisher中有这样一个方法publishEvent,用以发布事件,具体的实现类在AbstractApplicationContext中。
default void publishEvent(ApplicationEvent event) { this.publishEvent((Object)event); } void publishEvent(Object var1);
同样在AbstractApplicationContext中有方法registerListeners,可以注册监听器。
protected void registerListeners() { // 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 lisName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(lisName); } }
下面模拟Spring的监听器原理自己实现一个登陆登出事件的监听机制。
1 事件类(ApplicationEvent)
@Data public class Event implements Serializable { //事件源,谁触发的 private Object source; //触发类型的标记 private String trigger; //通知的目标对象 private Object target; //通知的目标的方法 private Method callback; //触发时间 private long time; public Event() { } public Event(Object target, Method callback) { this.target = target; this.callback = callback; } }
2 事件监听抽象类,或者接口(ApplicationListener)
/** * 事件监听器 */ @Slf4j public abstract class EventListener { /** * 存放事件 */ private List<Event> eventList = new ArrayList<>(); /** * 添加事件监听 */ public void addEvent(Object target, Method method) { Event event = new Event(target, method); eventList.add(event); } /** * 删除事件监听 */ public void removeEvent(Event e) { eventList.remove(e); } /** * 通过事件触发 */ public void trigger(Event event) { event.setSource(this); event.setTime(System.currentTimeMillis()); try { //调用指定的方法 event.getCallback().invoke(event.getTarget(), event); } catch (Exception e) { log.info(e.getMessage()); } } /** * 通过事件 类型出发,存储事件的集合可以使用Map,自定义类型属性 */ }
3 具体事件,继承自事件监听抽象类(ApplicationContext)
/** * 实例对象,具体的被观察者,即被监听的事件实现类 */ public class ConcreteSubject extends EventListener { /** * 模拟登陆推出,异常事件监听 */ public void login(Event loginEvent) { System.out.println("登陆事件"); super.trigger(loginEvent); } public void logout(Event logoutEvent) { System.out.println("登出事件"); super.trigger(logoutEvent); } public void exception(Event exceptionEvent) { System.out.println("异常事件"); super.trigger(exceptionEvent); } }
4 对于监听到指定事件给出相应的反馈类
/** * 观察者方法,模拟观察者观察到指定事件后相应的动作 */ public class LogEventCallback { public void login(Event event) { System.out.println("=======用户登陆======" + event); } public void logout(Event event) { System.out.println("=======用户登出======" + event); } public void exception(Event event) { System.out.println("=======异常======" + event); } }
5 测试类,测试登陆事件的监听机制
public class LogEventTest { public static void main(String[] args) throws NoSuchMethodException { LogEventCallback target = new LogEventCallback(); //通过反射获取指定的方法 Method login = target.getClass().getDeclaredMethod("login", Event.class); Method logout = target.getClass().getDeclaredMethod("logout", Event.class); Method exception = target.getClass().getDeclaredMethod("exception", Event.class); ConcreteSubject object = new ConcreteSubject(); //将监听事件放进监听类中,与Spring中的ApplicationContext功能相同 object.addEvent(target, logout); object.addEvent(target, login); object.addEvent(target, exception); object.trigger(new Event(target, login)); } }
相关文章推荐
- spring事件驱动模型--观察者模式在spring中的应用
- 观察者模式实际应用场景-----Spring事件机制
- spring事件驱动模型--观察者模式在spring中的应用
- AAAspring事件驱动模型--观察者模式在spring中的应用
- Spring 资源访问剖析和策略模式应用
- OpenJDK源码研究笔记(六)--观察者模式工具类(Observer和Observable)和应用示例
- jdk的PropertyChangeSupport属性值修改的观察者模式应用
- Android源码学习之观察者模式应用
- Event事件的应用之观察者模式
- 设计模式的C语言应用-观察者模式-第四章
- JAVA观察者模式在安卓中的应用
- 模式实践:观察者模式与Spring
- Spring 资源访问剖析和策略模式应用
- 观察者模式在One Order回调函数中的应用
- 观察者模式和Spring的结合
- Spring启动---单例模式实际应用
- iOS---KVO(Key Value Observing) 观察者模式之解析与应用
- 观察者模式生活中的一个应用
- 观察者模式的具体应用——通知(notification)机制和KVO(Key-Value-Observing)机制
- spring ApplicationListener实现Observer观察者模式