/** * */ public void addMyObjectListener(IMyObjectListener listener); /** * */ public void removeMyObjectListener(IMyObjectListener listener);
public interface IMyObjectListener { public void dataAdded(MyObjectEvent event); public void dataRemoved(MyObjectEvent event); public void dataChanged(MyObjectEvent event); }
public interface IListenerSupport<T> { /** * */ public void addListener(T listener); /** * */ public void removeListener(T listener); }
class MyObjectListenerSupport implements IMyObjectListener, IListenerSupport<IMyObjectListener> { public void addListener(IMyObjectListener listener) { // todo: listener } public void removeListener(IMyObjectListener listener) { // todo: listener } public void dataAdded(MyObjectEvent event) { // todo: dataAdded } public void dataRemoved(MyObjectEvent event) { // todo: dataRemoved } public void dataChanged(MyObjectEvent event) { // todo: dataChanged } }
public class MyObject { private MyObjectListenerSupport listeners = new MyObjectListenerSupport(); public void addMyObjectListener(IMyObjectListener listener) { listeners.addListener(listener); } public void removeMyObjectListener(IMyObjectListener listener) { listeners.removeListener(listener); } protected void fireDataAdded(MyObjectEvent event) { listeners.dataAdded(event); } protected void fireDataRemoved(MyObjectEvent event) { listeners.dataRemoved(event); } protected void fireDataChanged(MyObjectEvent event) { listeners.dataChanged(event); } }
public class ListenerSupportFactory { private ListenerSupportFactory() {} @SuppressWarnings("unchecked") public static <T> T createListenerSupport(Class<T> listenerInterface) { return (T)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { IListenerSupport.class, listenerInterface }, new ListenerInvocationHandler<T>(listenerInterface)); } private static class ListenerInvocationHandler<T> implements InvocationHandler { private final Class<T> _listener_iface; private final Logger _log; private final List<T> _listeners = Collections.synchronizedList(new ArrayList<T>()); private final Set<String> _current_events = Collections.synchronizedSet(new HashSet<String>()); private ListenerInvocationHandler(Class<T> listenerInterface) { _listener_iface = listenerInterface; // todo: find a more sensitive class for logger _log = LoggerFactory.getLogger(listenerInterface); } @SuppressWarnings({"unchecked", "SuspiciousMethodCalls"}) public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); // (1) handle IListenerSupport methods if (method.getDeclaringClass().equals(IListenerSupport.class)) { if ("addListener".equals(methodName)) { _listeners.add( (T)args[0] ); } else if ("removeListener".equals(methodName)) { _listeners.remove( args[0] ); } return null; } // (2) handle listener interface if (method.getDeclaringClass().equals(_listener_iface)) { if (_current_events.contains(methodName)) { throw new RuleViolationException("Cyclic event invocation detected: " + methodName); } _current_events.add(methodName); for (T listener : _listeners) { try { method.invoke(listener, args); } catch (Exception ex) { _log.error("Listener invocation failure", ex); } } _current_events.remove(methodName); return null; } // (3) handle all other stuff (equals(), hashCode(), etc.) return method.invoke(this, args); } } }
public class MyObject { private final MyObjectListener listeners; public MyObject() { listeners = ListenerSupportFactory.createListenerSupport(MyObjectListener.class); } public void addMyObjectListener(IMyObjectListener listener) { ((IListenerSupport<MyObjectListener>)listeners).addListener(listener); } public void removeMyObjectListener(IMyObjectListener listener) { ((IListenerSupport<MyObjectListener>)listeners).removeListener(listener); } /** * - **/ public void someSuperBusinessMethod(SuperMethodArgs args) { // todo: perform some cool stuff here // MyObjectEvent event = new MyObjectEvent(); // listeners.dataAdded(event); } }
Source: https://habr.com/ru/post/120643/
All Articles